Chrome Extension - Getting CORS error when trying to fetch() from background script with manifest v3

Viewed 2967

I'm getting a CORS error when I try to do a request from my Chrome Extensions's background script. The background script is bundled with webpack.

Note: If I convert manifest.json to version 2 - all works fine. But with v3 it gives

Access to fetch at 'https://example.com/api/user/login' from origin 'chrome-extension://exampleid' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

manifest.json

{
  "name": "__CE_APP_NAME__",
  "version": "__CE_APP_VERSION__",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.bundle.js",
    "type": "module"
  },
  "content_scripts": [
    {
      "matches": [
        "https://example.com/*"
      ],
      "js": ["content.bundle.js"]
    }
  ],
  "web_accessible_resources": [
    {
      "resources": [ "images/*", "*.css" ],
      "matches": [
        "https://example.com/*"
      ]
    }
  ],
  "permissions": [
    "storage",
    "unlimitedStorage",
    "cookies",
    "identity"
  ],
  "host_permissions": [
    "<all_urls>"
  ]
}

background.js

chrome.runtime.onMessage.addListener((req) => {
  if (req.type === 'auth/login') {
    login(req.payload);
  }

  return true;
});

interface LoginCredentials {
  email: string;
  password: string;
}

const login = (data: LoginCredentials) => {
  fetch(`${API_BASE_URL}/user/login`, {
    method: 'POST',
    body: new URLSearchParams({
      email: data.email,
      password: data.password
    })
  })
    .then((response) => console.log(response))
    .catch((error) => console.log(error));
};
3 Answers

This was an error with Chrome, it didn't apply the correct policy host setting when re-enabling the extension. If you're using any version below "94.0.4606.54 (Official Build)" you will have to do a manual reload (clicking the refresh button) after re-enabling the extension.

After reporting the error here I was informed that the bug was fixed with this commit, and it will be a part of Chrome 94.

If you download the Beta right now, you will notice that the error is fixed and it will officially come out in September 21, 2021 (tomorrow, as of this answer). You can check the schedule here

Thats how i solved this (append to manifest):

"content_security_policy": {
  "extension_pages": "default-src 'self'; connect-src https://* data: blob: filesystem:;"
}
  • default-src 'self' is used by default and chrome web store asks for it anyway. If not set it will error:
    CSP directive 'script-src' must be specified (either explicitly, or implicitly via 'default-src') and must whitelist only secure resources.

  • connect-src https://* data: blob: filesystem:; need for pass cors and

Applies to XMLHttpRequest (AJAX), WebSocket, fetch(), or EventSource. If not allowed the browser emulates a 400 HTTP status code.

I found info here

Here is my solution:

I believe it was not working because I was just doing Load Unpacked with the hopes that it will refresh the extension. I guess it was not fully refreshed so what needs to be done is an extra step. Click the Refresh button in the bottom right corner of the extension in the extensions page.

Hopefully soon there will be some better automated way for some kind of hot reload.

Related