Why does my http://localhost CORS origin not work?

JavascriptHtmlCorsXmlhttprequestXmlhttprequest Level2

Javascript Problem Overview


I am stuck with this CORS problem, even though I set the server (nginx/node.js) with the appropriate headers.

I can see in Chrome Network pane -> Response Headers:

Access-Control-Allow-Origin:http://localhost

which should do the trick.

Here's the code that I now use to test:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
   console.log('xhr loaded');
};
xhr.open('GET', 'http://stackoverflow.com/');
xhr.send();

I get

> XMLHttpRequest cannot load http://stackoverflow.com/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.

I suspect it's a problem in the client script and not server configuration...

Javascript Solutions


Solution 1 - Javascript

Chrome does not support localhost for CORS requests (a bug opened in 2010, marked WontFix in 2014).

To get around this you can use a domain like localho.st (which points at 127.0.0.1 just like localhost) or start chrome with the --disable-web-security flag (assuming you're just testing).

Solution 2 - Javascript

Per @Beau's answer, Chrome does not support localhost CORS requests, and there is unlikely any change in this direction.

I use the Allow-Control-Allow-Origin: * Chrome Extension to go around this issue. The extension will add the necessary HTTP Headers for CORS:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Access-Control-Expose-Headers: <you can add values here>

The source code is published on Github.

Note that the extension filter all URLs by default. This may break some websites (for example: Dropbox). I have changed it to filter only localhost URLs with the following URL filter

*://localhost:*/*

Solution 3 - Javascript

None of the extensions worked for me, so I installed a simple local proxy. In my case https://www.npmjs.com/package/local-cors-proxy It is a 2-minute setup:

(from their site)

> npm install -g local-cors-proxy > > API endpoint that we want to request that has CORS issues: > https://www.yourdomain.ie/movies/list > > Start Proxy: lcp --proxyUrl https://www.yourdomain.ie > > Then in your client code, new API endpoint: > http://localhost:8010/proxy/movies/list

Worked like a charm for me: your app calls the proxy, who calls the server. Zero CORS problems.

Solution 4 - Javascript

The real problem is that if we set -Allow- for all request (OPTIONS & POST), Chrome will cancel it. The following code works for me with POST to LocalHost with Chrome

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
	header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');    
	header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}	
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
} 
?>

Solution 5 - Javascript

Chrome will make requests with CORS from a localhost origin just fine. This isn't a problem with Chrome.

The reason you can't load http://stackoverflow.com is that the Access-Control-Allow-Origin headers weren't allowing your localhost origin.

Solution 6 - Javascript

Quick and dirty Chrome extension fix:

Moesif Orign & CORS Changer

However, Chrome does support cross-origin requests from localhost. Make sure to add a header for Access-Control-Allow-Origin for localhost.

Solution 7 - Javascript

Agreed! CORS should be enabled on the server-side to resolve the issue ground up. However...
For me the case was:

I desperately wanted to test my front-end(React/Angular/VUE) code locally with the REST API provided by the client with no access to the server config.

Just for testing

After trying all the steps above that didn't work I was forced to disable web security and site isolation trials on chrome along with specifying the user data directory(tried skipping this, didn't work).

For Windows
cd C:\Program Files\Google\Chrome\Application
Disable web security and site isolation trials
chrome.exe  --disable-site-isolation-trials --disable-web-security --user-data-dir="PATH_TO_PROJECT_DIRECTORY"

This finally worked! Hope this helps!

Solution 8 - Javascript

I think my solution to this might be the simplest. On my development machine, I added a fake domain in my hosts file similar to http://myfakedomain.notarealtld and set it to 127.0.0.1. Then I changed my server's CORS configuration (in my case an S3 bucket) to allow that domain. That way I can use Chrome on localhost and it works great.

Make sure your CORS configuration takes into account the entire hostname with port, ie. http://myfakedomain.notarealtld:3000

You can modify your hosts file easily on Linux, Mac, and Windows.

Solution 9 - Javascript

Chrome does allow CORS on localhost, I made it work with AWS API gateway/lambda. Viewing the network tab in the developer tools when sending http requests was very helpful. My problem was that my lambda function was not dealing with the preflight OPTIONS request, only POST and GET. I solved the issue by accepting OPTIONS requests and making sure to return the following headers from my API:

  • Access-Control-Allow-Origin: '*' (or website domain)
  • Access-Control-Allow-Methods: 'POST, GET, OPTIONS'
    • this is the preflight response telling chrome that we can now send a POST/GET request
  • Access-Control-Allow-Headers: 'Content-Type'
    • not sure if this is necessary, but it tells chrome that the request can include a Content-Type header

The important thing to note is that the browser sends 2 sets of headers.

  1. OPTIONS headers which includes
    • access-control-request-method: 'POST' (or whatever http method you are requesting)
    • origin: 'http://localhost:3000'; (website domain)
    • referer: 'http://localhost:3000/'; (I believe this is the full website path)
    • sec-fetch-mode: 'cors'
    • sec-fetch-site: 'cross-site'

if the response to request 1 is 200 code and the response header contains: 'access-control-allow-methods': 'POST' (or whatever the access-control-request-method was in the request),

  1. Actual request, for example: POST headers which includes
    • content-type: 'application/json'
    • origin: same as above
    • referer: same as above

There are more headers but I think these were the most important.

Solution 10 - Javascript

I decided not to touch headers and make a redirect on the server side instead and it woks like a charm.

The example below is for the current version of Angular (currently 9) and probably any other framework using webpacks DevServer. But I think the same principle will work on other backends.

So I use the following configuration in the file proxy.conf.json:

{
  "/api": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/api" : ""},
   "secure": false
 }
}

In case of Angular I serve with that configuration:

$ ng serve -o --proxy-config=proxy.conf.json

I prefer to use the proxy in the serve command, but you may also put this configuration to angular.json like this:

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },

See also:

https://www.techiediaries.com/fix-cors-with-angular-cli-proxy-configuration/

https://webpack.js.org/configuration/dev-server/#devserverproxy

Solution 11 - Javascript

The solution is to install an extension that lifts the block that Chrome does, for example:

Access Control-Allow-Origin - Unblock (https://add0n.com/access-control.html?version=0.1.5&type=install).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwhadarView Question on Stackoverflow
Solution 1 - JavascriptBeauView Answer on Stackoverflow
Solution 2 - JavascriptHanxueView Answer on Stackoverflow
Solution 3 - Javascriptdaniel pView Answer on Stackoverflow
Solution 4 - JavascriptgreensuisseView Answer on Stackoverflow
Solution 5 - JavascriptBradView Answer on Stackoverflow
Solution 6 - JavascriptkaleazyView Answer on Stackoverflow
Solution 7 - JavascriptAditya PatnaikView Answer on Stackoverflow
Solution 8 - JavascriptDustinAView Answer on Stackoverflow
Solution 9 - JavascriptMatthew PView Answer on Stackoverflow
Solution 10 - JavascriptJuri SinitsonView Answer on Stackoverflow
Solution 11 - JavascriptBibi RuizView Answer on Stackoverflow