224

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...

Liam
  • 22,818
  • 25
  • 93
  • 157
whadar
  • 3,209
  • 4
  • 17
  • 19
  • 54
    No, stackoverflow.com needs to set this header, not you. :x. What would be the point of same origin policy otherwise. – Esailija Jun 04 '12 at 14:44
  • 4
    Try accessing the server you've set up not stack overflow. ;) – Nek Jun 04 '12 at 15:10
  • DOH! Is there a way to tell chrome (or other browser), to get the resource even if the header is missing when my origin is localhost? – whadar Jun 04 '12 at 19:12
  • Run your codes in Chrome(20.0.1132.57, Windows 7), works fine. – imwilsonxu Sep 16 '12 at 16:13
  • 1
    If you're using localhost with a port this answer worked for me http://serverfault.com/a/673551/238261. – Nelu Sep 23 '16 at 16:03
  • Please Refer to this post for answer https://stackoverflow.com/questions/53528643/cross-origin-resource-sharing-cors-in-angular-or-angular-6-problem-while-you/53528644#53528644 – Ramesh Roddam Nov 28 '18 at 22:06
  • CORS works fine with localhost. This question isn't valid. – Brad Sep 15 '19 at 05:02

10 Answers10

270

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 lvh.me (which points at 127.0.0.1 just like localhost) or start chrome with the --disable-web-security flag (assuming you're just testing).

Cœur
  • 32,421
  • 21
  • 173
  • 232
Beau
  • 10,321
  • 7
  • 39
  • 35
  • 1
    This is not correct. I'm able to post to localhost with chrome – greensuisse Jun 15 '13 at 16:13
  • 33
    @greensuisse - it's not posting to localhost. It's posting *from* localhost that is the problem. – Cheeso Jul 31 '13 at 03:37
  • 12
    That bug is invalid (and has been marked as such - http://crbug.com/67743#c17). [Esailija's comment](http://stackoverflow.com/questions/10883211/deadly-cors-when-http-localhost-is-the-origin#comment14184025_10883211) is correct, adding these headers to localhost will not magically give you access to all other sites. It's the remote site that needs to be served with these headers. – Rob W Mar 22 '14 at 22:59
  • 12
    Other option: edit your hosts file so that local.[mysite].com points to 127.0.0.1, then make your CORS file allow *.[mysite].com – tom Jan 13 '15 at 18:16
  • 1
    local.[mysite].com nice trick. But is that not a loop hole for cors? What is stopping all others from doing the same (local.[mysite].com) to bypass the cors? – Gopalakrishna Palem Dec 10 '15 at 17:01
  • 1
    So to be extra clear, instead of `localhost:1111` or `localhost:[some other port number]`, use `http://lvh.me:1111` or `http://lvh.me[some other port number]` – Nick Manning Jan 22 '16 at 16:26
  • i am getting confused .. so will it work when i deploy the app? can other website my api? – Chhorn Elit Feb 07 '16 at 17:49
  • 2
    Chrome isn't even allowing domains that resolve to 127.0.0.1 now. Even after using a domain I added myself to `/etc/hosts`, I'm getting: `The 'Access-Control-Allow-Origin' header contains the invalid value 'myhost'.` – Nathan Osman May 24 '16 at 01:53
  • 6
    I faced the same problem with FireFox. I could only make it on Edge! Nice post though, fantastic! :) – Luis Gouveia Jul 20 '16 at 10:52
  • but once you go live, then you will have to remove the localhost option in your CORS settings right? – SuperUberDuper Jan 09 '17 at 10:33
  • @SuperUberDuper why? – neuhaus Mar 23 '18 at 15:23
  • 4
    see @Molomby's comment below "Chrome 100% does support cross-origin requests to and from localhost..." – Anthony Johnston Apr 09 '19 at 13:30
  • 1
    @FloatingRock in firefox newer versions like v76 and above on local host its not working giving error `SecurityError: The operation is insecure` – user889030 Jul 03 '20 at 06:07
  • The bug is marked as `wontfix` because they can't reproduce it. It is stated in the link that Chrome uses localhost for many automated tests and that localhost is indeed supported. – Mark Hennings Aug 28 '20 at 13:59
  • This answer is not correct. Chrome supports localhost w/ CORS. The bug was invalid, and most of the examples of people having issues are around either putting the headers in the wrong place, or not having matching ports (which would be considered a different domain). – Matthew Dean Feb 16 '21 at 19:14
  • This is not correct, I was able to post **from** localhost, to the google online firebase realtime database service. It initially did not work because I formatted the URL incorrectly (missed to add .json to the end of the URL), which lead me to this answer. After correcting the URL, there is no need for any workaround for a localhost alias or a special startup argument, it just works out of the box. – Alex G Feb 23 '21 at 12:07
69

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:*/*
Jonathan Arbely
  • 162
  • 1
  • 13
Hanxue
  • 10,413
  • 12
  • 81
  • 120
  • 20
    If you read the issue @beau links to you'll see Chrome 100% does support cross-origin requests to and from localhost. The issue was closed in 2014 because it couldn't be reproduced. The rest of the noise in that thread is people with misconfigured non-origin servers (as with the original question here). – Molomby Mar 05 '19 at 05:51
  • 2
    Worked like charm for me on chrome – Aakash Sahai Jul 18 '19 at 22:06
  • 4
    Working link: https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf – paddotk Oct 25 '19 at 12:43
  • 4
    This Extension doesn't work with ```Access-Control-Allow-Credentials: true``` because it sets ```Access-Control-Allow-Origin``` to ```*``` and having both ```true``` and ```*``` is blocked by browsers. If using credentials true, you must use non-wildcard origin. I recommend Moesif Origins and CORS Changer Extension which allows you to change headers however you want. – Samuel Feb 04 '20 at 13:59
  • Maybe I'm doing something wrong, but this extension no longer seems to work for me. – James Parker Apr 08 '20 at 13:41
  • Is there an extension that does the same thing for Firefox? – Chiwda Jul 31 '20 at 03:46
  • 1
    @Chiwda you can find the above-mentioned and loads more here: https://addons.mozilla.org/en-GB/firefox/search/?platform=mac&q=cors – redplanet Sep 29 '20 at 21:04
  • Doesn't work. It only allows for GET requests only – Yonatan Nir Jan 10 '21 at 12:18
21

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);
} 
?>
Yves M.
  • 26,153
  • 20
  • 93
  • 125
greensuisse
  • 1,523
  • 15
  • 16
18

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.

daniel p
  • 217
  • 2
  • 5
  • Worked for me (http server at http ://localhost:81/sse): lcp --proxyUrl http ://localhost:81/sse. In the code change to http ://localhost:8010/proxy/sse (as given to you on the command line by lcp. – svenema Feb 03 '21 at 17:51
10

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.

Brad
  • 146,404
  • 44
  • 300
  • 476
4

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.

kaleazy
  • 4,966
  • 2
  • 40
  • 47
  • i added this extension to my Opera and now its f'd up. i can never tell when its on and off so i use firefox for work. and opera for development. google suit doesnt like it, and other things dont either. – Maddocks Dec 03 '19 at 17:52
4

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.

DustinA
  • 351
  • 2
  • 9
3

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!

Aditya Patnaik
  • 703
  • 7
  • 17
-1

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

Community
  • 1
  • 1
Juri Sinitson
  • 785
  • 8
  • 12
-3

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).

Bibi Ruiz
  • 25
  • 5