Are you doing the request from localhost or direcly executing HTML?
– MD. Sahib Bin MahboobNov 17 '13 at 19:31

@MD.SahibBinMahboob If I understand your question I do request from localhost - I have page on my computer and just run it. When I deploy site on hosting it's gave same result.
– Mr JediNov 17 '13 at 19:43

is the domain of your executed page and requested domain name same or different?
– MD. Sahib Bin MahboobNov 17 '13 at 19:47

41 Answers
41

If I understood it right you are doing an XMLHttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.

Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.

You're right. I doing request to different domain than my page is. API is on server and I run request from localhost. Before I accept answer can you explain me what mean "executing the request directly" ? POSTMAN don't use domain?
– Mr JediNov 17 '13 at 19:54

147

The browser is not blocking the request. The only browsers that outright block cross-origin ajax requests is IE7 or older. All browsers, other than IE7 and older, implement the CORS spec (IE8 & IE9 partially). All you need to do is opt-in to CORS requests on your API server by returning the proper headers based on the request. You should read up on CORS concepts at mzl.la/VOFrSz. Postman sends requests via XHR as well. If you are not seeing the same problem when using postman, this means that you are unknowingly not sending the same request via postman.
– Ray NicholusNov 17 '13 at 20:01

This is not a fix for production or when application has to be shown to the client, this is only helpful when UI and Backend development are on different servers and in production they are actually on same server. For example: While developing UI for any application if there is a need to test it locally pointing it to backend server, in that scenario this is the perfect fix. For production fix, CORS headers has to be added to the backend server to allow cross origin access.

The easy way is to just add the extension in google chrome to allow access using CORS.

This is great but clients can't be asked to launch chrome this way to enforce an internal requirement for a webservice call.
– TaersiousSep 24 '15 at 17:55

78

this shouldn't be accepted as an answer, installing a third party plugin to fix your app, rather than understanding CORS and fixing your app, how will other people use your api? will you make them all install this plugin
– James KirkbyApr 28 '16 at 11:10

4

I installed this extension and did a request, than checked the request in fiddler, the following was specified -> Origin: evil.com . Looks like this extension is changing the Origin to evil.com
– wagwanJahManMay 10 '16 at 12:54

14

I think this is a really great answer if you don't need a permanent fix or if you only need CORS disabled temporarily. That's what I needed, and this solution worked great. Obviously, this could never be considered a permanent solution.
– jtcotton63Mar 24 '17 at 0:44

2

This answer is fine. For dev work, this got me up-and-running asap and I will come back and find the proper fix later...
– Adam HughesOct 19 '17 at 19:48

The advent of JSONP — essentially a consensual cross-site scripting hack — has opened the door to powerful mashups of content. Many prominent sites provide JSONP services, allowing you access to their content via a predefined API.

How does this have so many up votes when you cant use jsonp with POST requests?!?!
– fatlogAug 7 '15 at 15:06

8

When you use JSONP, $.ajax will ignore type, so it's always GET which means this answer will always work.
– noobOct 6 '16 at 3:56

8

Also note that JSONP is not directly interchangeable with JSON. You need the server to return data in JSONP format too. Simply changing the dataType in the AJAX request settings alone isn't going to work.
– Rory McCrossanSep 7 '17 at 10:19

It's very simple to solve if you are using PHP. Just add the following script in the beginning of your PHP page which handles the request:

<?php header('Access-Control-Allow-Origin: *'); ?>

Warning: This contains a security issue for your PHP file that it could be called by attackers. you have to use sessions and cookies for authentication to prevent your file/service against this attack. Your service is vulnerable to cross-site request forgery (CSRF).

If you are using Node-red you have to allow CORS in the node-red/settings.js file by un-commenting the following lines:

// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
origin: "*",
methods: "GET,PUT,POST,DELETE"
},

You shouldn't turn off CORS because you don't know what its for. This is a terrible answer.
– meagar♦Dec 30 '14 at 6:12

105

Even though it might not be secure, the question was not about security, but how to accomplish the task. This is one of the options that a developer has to choose from when dealing with cross-domain AJAX requests. It helped me resolve the issue, and for my application, I don't care where the data came from. I sanitize all the input with PHP on the destination domain, so, if someone wants to post some junk to it, let them try. The main point here is, cross-domain AJAX can be allowed from the destination domain. +1 for the answer.
– ZurabWebFeb 26 '15 at 16:37

18

While I agree with the general message Piero is giving, that it's not specifically about security, but security is a concern. I think this should have at least said something like "This is generally bad! Don't do this unless you know what you're doing! Here's more documentation on it: ...", and maybe briefly explain why. I would hate for someone to come on here and just think "Oh, I can just add/adjust this header and I'm good!" and not know the full ramifications. I mean, it's kind of on them to research and all, but still.
– Thomas F.Oct 15 '15 at 14:55

I wish someone shared this site with me long ago http://cors.io/ it would have saved a ton of time compared to building and relying on my own proxy. However, as you move to production, having your own proxy is the best bet since you still control all aspects of your data.

I am giving you the up vote because this is exactly what I needed. But think it is a bad idea to promote the "*" example without explaining that it will allow any connection and should not be used in production. This is explained at the MDN link developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.
– robJun 9 '17 at 9:12

@rob thanks for your comment. You are right, we should specify which origins are allowed to use the resources. But in case, the resources use for public purpose and we don't know the consumers, I think we should go with "*" if I am not wrong.
– Nguyen TranJun 9 '17 at 11:08

I have used this concept and my issue is resolved in nodejs. Thanks
– Deepak BhattaAug 20 '17 at 7:29

There's a cross-domain issue using Ajax. You must be sure you are accessing your files on the same http:// path without www. (or access from http://www. and post to the same path including www.) which the browser considers as another domain when accessing via a www. path, so you see where the problem is. You are posting to a different domain and the browser blocks the flow because of the origin issue.

If the API is not placed on the same host that you are requesting from, the flow is blocked, and you will need to find another way to communicate with the API.

yup, i was forced to this in my phonegap app, var app_url = location.protocol + '//' + location.host+'/api/. the problem was the site with www. prepended would bring that error.
– Sir LojikApr 27 '15 at 12:26

Summary: A pure JavaScript CORS alternative/polyfill. No server configuration required - just add a proxy.html on the domain you wish to communicate with. This library uses XHook to hook all XHR, so XDomain should work in conjunction with any library.

Are your referring to this example code from main.min.js?: t.post("https://wiki.wikinomad.com/api.php?origin=https://www.wikinomad.com", n, o).then(function(e) {.... If so, isn't it true that this way of specifying an origin requires that the PHP being served from the "backend" is coded to support it, and this answer will not work otherwise?
– CODE-REaDFeb 15 '18 at 20:18

1

@CODE-REaD, yes that's correct that the backend needs to support CORS as well.
– Ganesh KrishnanJan 19 at 17:55

I had a problem with this when I used AngularJS to access my API. The same request worked in SoapUI 5.0 and ColdFusion. My GET method already had Access-Control-Allow-Origin header.

I found out that AngularJS makes a "trial" OPTIONS request. ColdFusion, by default, generates OPTIONS method, but it doesn’t have much, these headers specifically. The error was generated in response to that OPTIONS call, and not to my intentional call to GET. After I added OPTIONS method below to my API, the problem has been resolved.

Excellent. Now I have to go around to my 100,000 users and disable their web security on chrome.
– Ganesh KrishnanJul 6 '16 at 6:08

7

@GaneshKrishnan The questioner seems to be a developer and his question (in my opinion) seems for development purposes, as my problem was. And yes, if you want to hack your users, go around them and disable their web security on Chrome :)
– Mohammad AlBannaJul 6 '16 at 18:37

https://github.com/Rob--W/cors-anywhere/ provides (Node.js) code you can use to set up and run your own CORS proxy. It’s actively maintained and provides a number of features for controlling the proxy behavior beyond just the basic sending of the correct Access-Control-* response headers.

In the case where a site you need to make a request to and get a response from doesn’t return the Access-Control-Allow-Origin response header, browsers are always going to block cross-origin requests made to it directly by your client-side JavaScript code from working. And so if the site is not one you control and can configure behavior for, the only thing that will work in that case is proxying the requests—either through your own proxy you run yourself or through an open proxy.

As with other open proxies mentioned here (a couple of which at least don’t seem to be available any longer), the way it works is that instead of having your client code send a request directly to, e.g., http://foo.com you send it to https://cors-anywhere.herokuapp.com/http://foo.com and the proxy adds the necessary Access-Control-* headers to the response the browser sees.

If you are using Entity Framework, it seems that this error will sometimes be thrown even if you have CORS enabled. I figured out that the error occurred because of a missing finalization of the query. I'm hoping this will help others in the same situation.

The following code can throw the XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. error:

I was successfully able to solve (in my case for fonts) using htaccess but obviously, OP is asking little different. But you can use FileMatch pattern and add any sort of extension so that it won't give cros error.

Popular question -- Another thing to look at if you've read this far and nothing else has helped. If you have a CDN such as Akamai, Limelight or similar, you might want to check the cache key you have for the URI of the resource. If it does not include the Origin header value you may be returning a response cached when requested from another Origin. We just spent half a day debugging this. The CDN configuration was updated to only include the Origin value for a few select domains that are ours and set it to null for all others. This seems to work and allows browsers from our known domains to view our resources. Certainly all the other answers are prerequisites to getting here but if the CDN is the first hop from your browser this is something to review.

In our case we could see some requests making it to our service but not nearly the volume the site was sending. That pointed us to the CDN. We were able to go back and see the original request was served from a direct request, not part of a browser AJAX call and the response header Access-Control-Allow-Origin was not included. Apparently the CDN cached this value. The Akamai CDN configuration tweak to consider the Origin request header value as part of the match seems to have made it work for us.

Yes but we don't. A service exposed to the world can be DOS'ed via cache explosion by sending bogus values. Akamai has some help in this area to reduce DOS exposure. My point is that you can do everything listed and still have a problem because of caching.
– No Refunds No ReturnsSep 7 '17 at 22:42

The question says "I know that the API or remote resource must set the header, but why did it work when I made the request via the Chrome extension Postman?". This is not an answer to the question that was asked.
– QuentinSep 13 '17 at 8:39

@Quentin You are so RIGHT! however this is the #1 hit for many searches on this topic, there are already a variety of answers that vary from the exact question yet provide useful information AND this was what we discovered on Sept 7 after exhausting all of the threads. I appreciate your downvote. Future readers will be also able be able to weigh whether or not this "not an answer" was helpful by voting, perhaps even differently from you. There is at least one other person who has already publicly disagreed with your opinion. Will be interesting to see how the voting goes from here........
– No Refunds No ReturnsSep 13 '17 at 14:54

First you can take a look at MDN CORS Doc to know what CORS is. As far as I know, CORS is about whether to allow Origin Of Request to access Server Resource or not.

And you can restrict which request origin can access the server by setting Access-Control-Allow-Origin at Header of Server Response.

For example, Setting following header in Server Response means that only request sent from http://foo.example can access your server:

Access-Control-Allow-Origin: http://foo.example

and following allow request sent from any origin(or domain):

Access-Control-Allow-Origin: *

And as I know in the error message, requested resource means resource of server, so No 'Access-Control-Allow-Origin' header is present on the requested resource. means you didn't set Access-Control-Allow-Origin header in your Server Response, or maybe you set but the origin of request isn't list in Access-Control-Allow-Origin so request is not allowed access:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

In GoLang, I use gorilla/mux package to build API server at localhost:9091, and I allow CORS by add "Access-Control-Allow-Origin", "*" to header of response:

Then, create a simple PHP file called proxy.php to wrap your POST data and append them to the remote URL server as a parameters. I give you an example of how I bypass this problem with the Expedia Hotel search API:

A lot of times this happens to me from javascript to my php api, because one of a few reasons.
I forget to put the <?php header('Access-Control-Allow-Origin: *'); ? is one. This is helpful for cross sub domain access. Another reason, is because in jQuery ajax request I am specifying a specific dataType and returning a different dataType, so it throws an error.

The Last and most prominent reasoning for this error is there is a parse error on the page you are requesting. If you hit that page url in your browser than more than likely you will see a parse error and you will have a line number to address the issue.

I hope this helps someone. It took me a while each time to debug this and I wish I had a checklist of things to verify.

The question says "I know that the API or remote resource must set the header, but why did it work when I made the request via the Chrome extension Postman?". This is not an answer to the question that was asked.
– QuentinSep 13 '17 at 8:40

CORS is "Cross Origin Resource Sharing" and is a way to send a cross-domain request. Now the XMLHttpRequest2 and Fetch API both support CORS.

But it has its limits. Server need to specific claim the Access-Control-Allow-Origin, and it can not be set to '*'.

And if you want any origin can send request to you, you need JSONP (also need to set Access-Control-Allow-Origin, but can be '*').

For lots of request way if you don't know what to choose, I think you need a fully functional component to do that. Let me introduce a simple component catta

If you are using a modern browser (> Internet Explorer9, Chrome, Firefox, Edge, etc.), it is very recommended you use a simple, but beautiful component, https://github.com/Joker-Jelly/catta. It has no dependencies, is less than 3 KB, and it supports Fetch, Ajax and JSONP with same dead-simple syntax and options.

I have an IIS site which is local that is hosting my API. I have an external site which is accessed outside the local network. I am trying to execute the API from the external site, I have CORS enabled for the external site (e.g. [EnableCors(origins: "http://websitelink.com", headers: "*", methods: "*")] but it is not working. Any idea? forums.asp.net/p/2117965/…
– Si8Mar 24 '17 at 14:12

Most of these answers tell users how to add CORS headers to a server they control.

However, if you need data from a server you don't control in a webpage, one solution is to create a script tag on your page, set the src attribute to the api endpoint that doesn't have CORS headers, then load that data onto the page:

Excellent answer, but if script is not in correct format, then you can't reach its code (script.text= empty). What to do in this case? How to reach its code?
– Angel TFeb 8 '18 at 6:52

How to prevent the execution of the script (maybe as comment it all)?
– Angel TFeb 8 '18 at 7:16

And another interesting thing: Only IE11 with Enabled "Access data sources across domains" can access cross-domain (without of need to control server to modificate Origin!. All rest major browsers can't
– Angel TFeb 8 '18 at 8:14

The question says "I know that the API or remote resource must set the header, but why did it work when I made the request via the Chrome extension Postman?". This is not an answer to the question that was asked.
– QuentinSep 13 '17 at 8:40

Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).