'Access to fetch has been blocked by CORS policy' Chrome extension error
Asked Answered
B

4

25

I am trying to get data from an external API from the background script of my Chrome extension, using messaging to initiate the call from the content script and get the results. I have no control over the external API. The documentation from that API says to use script tags to get a jsonp response, but if I understand correctly, that shouldn't matter when the below items are implemented. Am I wrong?

  • the fetch() is in the background script
  • "\*://\*/" is in my permissions in the manifest (I will change that if I can get this to work, just eliminating that possibility)
  • The extension is 'packed'

Error: Access to fetch at 'https://external-api.com' from origin 'chrome-extension://bunchofchars' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.

Any clue as to what I'm doing wrong?

background.js

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
      fetch('https://api.com/' + request.user + 'restofurl',
          {
            method: 'get',
            headers: {'Content-Type':'application/json'}
          })
//          .then(response => parseResults(response.results))
          .then(response => sendResponse({result: response.results}))
//          .catch(error => ...)
      return true;
  });

content.js

(() => {
    function foo() {

        var parent = document.getElementById('someId');
        var username = parent.getElementsByTagName('a')[6].innerHTML;
        chrome.runtime.sendMessage({user: username}, function(response) {
            console.log(response.result);
        });
    window.addEventListener('load', foo);

})();
Braley answered 7/11, 2020 at 21:46 Comment(1)
Assuming your background.js is not a misleadingly named content script but is a background script declared as one in manifest.json and loaded only in that one place, the problem sounds like you didn't reload the extension after editing manifest.json so *://*/ permission isn't actually applied. If you did, try specifying a different mode e.g. mode: 'same-origin'Stutter
M
43

Manifest version 3 uses the host_permissions field

"host_permissions": ["https://api.com/*"],
Miscreated answered 18/4, 2021 at 23:2 Comment(3)
Pay attention, If user change the extension’s site access to On click, the API request from the background still encounter CORS error.Geerts
@Geerts what is the solution for this case?Causal
@Causal It have to add CORS headers (Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-Methods, Access-Control-Allow-Headers) from chrome-extension://<your-extension-id> for related API. We add these headers in Nginx server for now.Geerts
B
1

Maybe your extension is allowed only to read and modify on this particular site.

Let extensions read and change site data

  • When you click the extension: This setting only allows the extension to access the current site in the open tab or window when you click the extension. If you close the tab or window, you’ll have to click the extension to turn it on again.
  • On [current site]: Allow the extension to automatically read and change data on the current site.
  • On all sites: Allow the extension to automatically read and change data on all sites.

Try to change to the last option. This should change CORS policy.

Bidarka answered 13/1, 2021 at 19:56 Comment(0)
C
0

I had the same problem developing a new extension for manifest v3. Like has been said, a cors error can be linked to a missing host_permissions entry.

But it can also been related to the global site setting of your extension. If the extension is not configured to work on all sites, you have to add the url of the api in the matches entry of the content_scripts

This is not logical at all, since it is supposed to set the permission for the content scripts, but it is also setting the permission to use the whole extension on other sites.

Cupola answered 30/3 at 8:40 Comment(0)
R
-2

Ideally, cors issue must be resolved on the server-side by adding specific origins. This is because all modern browsers such as chrome block the requests originating from the same machine.

In this case, however, please try to use additional fetch parameters as follows:

fetch(url, {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'no-cors', // no-cors, *cors, same-origin

headers: {
  //'Content-Type': 'application/json'
  // 'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
Reasonless answered 7/11, 2020 at 22:10 Comment(1)
Adding 'no-cors' won't work for me because I need response data.Braley

© 2022 - 2024 — McMap. All rights reserved.