How to fix “Access to XMLHttpRequest has been blocked by CORS policy” in Chrome

Cross-Origin Resource Sharing (CORS) is a mechanism based on HTTP headers that allows browsers to identify which request comes from allowed domain list, at the same time filter out unknown requests. Browsers make a “preflight” request to the server hosting the cross-origin resource in order to check that the server will permit the actual request. In that preflight, the browser sends information about the HTTP method and headers that will be used later in the actual request.

Fetching data from sites and APIs that enforced CORS policy without proper headers can lead to "Access to XMLHttpRequest has been blocked by CORS policy" error message in Chrome DevTools. The error comes in several forms, include useful information for debugging.

This article is going to show you how to fix "Access to XMLHttpRequest has been blocked by CORS policy" in various scenarios.

Access to XMLHttpRequest has been blocked by CORS policy in the wild

Access to XMLHttpRequest has been blocked by CORS policy : No 'Access-Control-Allow-Origin' header is present on the requested response

Just as what Chrome DevTools says, "No 'Access-Control-Allow-Origin' header is present on the requested response" error means the response does not have the proper Access-Control-Allow-Origin header in place.

In this case, you have a few options :

  • Use a Chrome extension to add Access-Control-Allow-Origin header into every response.

    To find one of them, just head over to Chrome Webstore and type in "CORS", dozens will show up in the search result. Or you can install CORS Helper, CORS Unblock or dyna CORS right away.

  • Redirect your request through a CORS proxy.

    You can easily spin up your own proxy using open source code from https://github.com/Rob--W/cors-anywhere/. Deploying to Heroku takes only 2-3 minutes, or you can use the original developers demo for quick, one-time usage : https://cors-anywhere.herokuapp.com/.

    To use the proxy, you have to prefix your request URL with the proxy URL so that it would look like this : https://cors-anywhere.herokuapp.com/https://example.com. The proxy will then forward your request to the original server, then grabs the response, adds Access-Control-Allow-Origin header to the response before pass it to you.

Access to XMLHttpRequest has been blocked by CORS policy : Response to preflight request doesn't pass access control check

"Response to preflight request doesn't pass access control check" can comes with additional message about the actual error. If you encounter one of these, you may consider my recommended options in the next section.

The 'Access-Control-Allow-Origin' header contains multiple values, but only one is allowed

The Access-Control-Allow-Origin header doesn't allow for more than one origin to be specified by design. If you are a fellow web developer, my advice is to carefully review your code that involves setting up CORS headers. You may set the Access-Control-Allow-Origin twice, or adds too many values to it instead of replacing the value. Most of the time, the error is related to the source code.

If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled

An opaque response is for a request made for a resource on a different origin that doesn't return CORS headers. With an opaque response we won't be able to read the data returned or view the status of the request, meaning we can't check if the request was successful or not.

In this situation, you need to modify your code so that the request to the different origin does not contain CORS headers. In JavaScript, the behaviour can be achieved by passing {mode: 'no-cors'} in fetch:

fetch('http://some-site.com/cors-disabled/some.json', {mode: 'no-cors'})

Opaque responses can't be accessed by JavaScript, but you can still cache them with the Cache API and respond with them in the fetch event handler in a service worker. So they're useful for resources that you can't control (e.g. resources on a CORS-less CDN) but still want to cache.

Access-Control-Allow-Origin header must not be the wildcard

For a request that includes credentials, browsers won’t let your front-end JavaScript code access the response if the value of the Access-Control-Allow-Origin response header is set to *. Instead, the value of the header must exactly match your front-end origin, e.g http://where_you_send_request.com.

If you are using any "Easy CORS" Chrome extension like Allow CORS: Access-Control-Allow-Origin or CORS Unblock, disable it and the problem should disappear.

If you have access to the server, you can configure the server to grab the value of the Origin header the client sends, then echo it back to Access-Control-Allow-Origin response header. In nginx configuration language, the setting can be set by placing the line below into the config file.

add_header Access-Control-Allow-Origin $http_origin

You can find more details at Credentialed requests and wildcards in the MDN HTTP access control (CORS) article.

Click to rate this post!
[Total: 34 Average: 5]

Leave a Comment