I am trying to do authorization using JavaScript by connecting to the RESTful API built in Flask.

As result I get:

XMLHttpRequest cannot load http://myApiUrl/login. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access.

I know that the API or remote resource must set the header, but why did it work when I tested authorization in the Chrome extension POSTMAN?

This is the request code:

$.ajax({
    type: "POST",
    dataType: 'text',
    url: api,
    username: 'user',
    password: 'pass',
    crossDomain : true,
    xhrFields: {
        withCredentials: true
    }
})
    .done(function( data ) {
        console.log("done");
    })
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
        alert(textStatus);
    });
share
9  
Are you doing the request from localhost or direcly executing HTML? – MD. Sahib Bin Mahboob Nov 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 Jedi Nov 17 '13 at 19:43
    
is the domain of your executed page and requested domain name same or different? – MD. Sahib Bin Mahboob Nov 17 '13 at 19:47
1  
much related: stackoverflow.com/questions/10143093/… – cregox Jul 7 '14 at 16:39
3  
For anyone looking for more reading, MDN has a good article all about ajax and cross origin requests: developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_COR‌​S – Sam Eaton Jun 18 '15 at 15:22

24 Answers 24

up vote 692 down vote accepted

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.

When you are using postman they are not restricted by this policy. Quoted from Cross-Origin XMLHttpRequest:

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.

share
1  
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 Jedi Nov 17 '13 at 19:54
63  
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 Nicholus Nov 17 '13 at 20:01
7  
@MD.SahibBinMahboob Postman is NOT sending a request "from your java/python" code. It is sending the request directly from the browser. XHR in Chrome extensions does work a bit differently, especially when cross-origin requests are involved. – Ray Nicholus Nov 17 '13 at 20:08
5  
@yves it's the browser who actually imposed the rule. So initiating request from any places rather than browser should work file – MD. Sahib Bin Mahboob Aug 5 '15 at 12:54
1  
@SuhailGupta, if you allow origins in your server, it will be allowed to do the request which is actually known as CORS. – MD. Sahib Bin Mahboob Feb 29 '16 at 5:07

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.

(https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en-US)

Just enable this extension whenever you want allow access to no 'access-control-allow-origin' header request.

Or

In Windows, paste this command in run window

chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

this will open a new chrome browser which allow access to no 'access-control-allow-origin' header request.

share
    
I am trying to use that CORS tool but I dont know how to use it. Can you help me with that? – Ruby_Pry May 14 '15 at 18:09
60  
This is great but clients can't be asked to launch chrome this way to enforce an internal requirement for a webservice call. – Taersious Sep 24 '15 at 17:55
21  
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 Kirkby Apr 28 '16 at 11:10
3  
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 – wagwanJahMan May 10 '16 at 12:54
1  
This extension is working like a charm. But really what they are doing internally? Is there a way to do the same in Javascript or Jquery way rather than using a plugin ? – sms May 11 '16 at 11:07

If you can deal with JSON in return, then try using JSONP (note the P at the end) for speaking between domains:

$.ajax({
  type: "POST",
  dataType: 'jsonp',
  ...... etc ....

The advent of JSONP — essentially a consensual cross-site scripting hack — has opened the door to powerful mashups of content.

https://learn.jquery.com/ajax/working-with-jsonp/

share
2  
With NodeJs with datatype json worked, with ASP.Net this was the culprit – Gaizka Allende May 15 '14 at 9:36
59  
Be aware jsonp doesn't work for POST content. More discussions here. – Prabu Raja Nov 13 '14 at 0:28
39  
How does this have so many up votes when you cant use jsonp with POST requests?!?! – fatlog Aug 7 '15 at 15:06
4  
When you use JSONP, $.ajax will ignore type, so it's always GET which means this answer will always work. – jcoder Oct 6 '16 at 3:56
6  
Looks like over 200 people just don't GET it – cs01 Nov 23 '16 at 21:53

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 CROS 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"
},
share
200  
The question was not about PHP at all. – mknaf Dec 10 '14 at 14:32
49  
and it's not secure – llazzaro Dec 20 '14 at 19:25
61  
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
60  
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. – Piero Feb 26 '15 at 16:37
6  
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.

All you need:

http://cors.io/?http://HTTP_YOUR_LINK_HERE

share
15  
What are the downsides of this? Are those guys intercepting my data? – Sebastialonso Aug 21 '15 at 16:33
5  
cors.io/?u=HTTP_YOUR_LINK_HERE (small correction) – jkpd Sep 17 '15 at 13:05
55  
I don't think sending your data over 3rd party proxy is a good idea – Daniel Alexandrov Oct 16 '15 at 14:07
6  
One downside is they are sometimes overloaded, as they are now. This application is temporarily over its serving quota. Please try again later. – Daniel Hickman Feb 20 '16 at 7:52
11  
try too https://crossorigin.me/http://example.com – KingRider Apr 15 '16 at 15:05

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.

share
    
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 Lojik Apr 27 '15 at 12:26

If you are using Node.js, try it:

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

More information: CORS on ExpressJS

share

Try XDomain,

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.

share

For c# web services - webapi

Please add the following code in your web.config file under <system.webServer> tag. This will work

<httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
</httpProtocol>

Please make sure you are not doing any mistake in the ajax call

jQuery

$.ajax({
    url: 'http://mysite.microsoft.sample.xyz.com/api/mycall',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    type: "POST", /* or type:"GET" or type:"PUT" */
    dataType: "json",
    data: {
    },
    success: function (result) {
        console.log(result);    
    },
    error: function () {
        console.log("error");
    }
});
share

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.

<cffunction name="optionsMethod" access="remote" output="false" returntype="any" httpmethod="OPTIONS" description="Method to respond to AngularJS trial call">
    <cfheader name="Access-Control-Allow-Headers" value="Content-Type,x-requested-with,Authorization,Access-Control-Allow-Origin"> 
    <cfheader name="Access-Control-Allow-Methods" value="GET,OPTIONS">      
    <cfheader name="Access-Control-Allow-Origin" value="*">      
    <cfheader name="Access-Control-Max-Age" value="360">        
</cffunction>
share
4  
It's not angular that makes the OPTIONS request, it's the browser based on the request! – Narretz Oct 12 '15 at 17:36
1  
Narretz - calling API via browser doesn't produce this error, nor it makes an extra options call. When angular used it does. – Leonid Alzhin Nov 17 '15 at 0:20
2  
Narretz is right, it is not related to angular. It's related to how CORS works. – Emile Bergeron Oct 18 '16 at 15:23

I had the following configuration, resulting in the same error, when requesting responses from the server.

Server-side: SparkJava --> provides the REST-API
Client-side: ExtJs6 --> provides Browser rendering

On the server-side I had to add this to the response:

Spark.get("/someRestCallToSpark", (req, res) -> {
    res.header("Access-Control-Allow-Origin", "*"); //important, otherwise its not working 
    return "some text";
 });

On the client-side I had to add this to the request:

Ext.Ajax.request({
    url: "http://localhost:4567/someRestCallToSpark",
    useDefaultXhrHeader: false, //important, otherwise its not working
    success: function(response, opts) {console.log("success")},
    failure: function(response, opts) {console.log("failure")}
});
share
    
Had the same architecture, therefore the same problem, and this solve it. – Fafhrd Oct 7 '15 at 19:03
2  
This is not a good idea to allow requests from any domain. You should restrict it to trusted domain only. – MD. Sahib Bin Mahboob Jan 15 '16 at 5:36
    
If you are the host of both domains, then it is common practice to enable this type of requests. – kiltek May 25 '16 at 8:42

Based on shruti's answer, I've created a shortcut of Chrome browser with needed arguments: enter image description here enter image description here

share
1  
@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 Jul 6 '16 at 18:37

If you do NOT

  1. want to disable web security in Chrome
  2. use JSONP
  3. use a third party site to re-route your requests

and you are sure that your server has CORS enabled then (test CORS here: http://test-cors.org/)

Then you need to pass in origin parameter with your request. This origin MUST match the origin that your browser sends with your request.

You can see it in action here: http://www.wikibackpacker.com/app/detail/Campgrounds/3591

The edit functionality sends a GET & POST request to a different domain for fetching data. I set the origin parameter which resolves the issue. The backend is a mediaWiki engine.

tldr: Add "origin" parameter to your calls which must be the Origin parameter that your browser sends (you cannot spoof the origin parameter)

share

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:

using (DBContext db = new DBContext())
{
    return db.Customers.Select(x => new
    {
        Name = x.Name,
        CustomerId = x.CustomerId,
    });
}

To fix it, a finalization call like .ToList() or .FirstOrDefault() at the end of the query is required, like so:

using (DBContext db = new DBContext())
{
    return db.Customers.Select(x => new
    {
        Name = x.Name,
        CustomerId = x.CustomerId,
    }).ToList();
}
share
    
That seems like just an error that will happen in any application of entity framework if you don't finalize the query. Not really related to CORS or the OP's question. – Gary Jan 4 '16 at 21:20
1  
It may very well not be related to CORS, but it throws an error that sounds like it has something to do with CORS; hence my answer. – Loyalar Feb 17 '16 at 6:52

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.

share

In my case I was using JEE7 JAX-RS application and following tricks worked perfectly for me:

@GET
    @Path("{id}")
    public Response getEventData(@PathParam("id") String id) throws FileNotFoundException {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("/eventdata/" + id + ".json");
        JsonReader jsonReader = Json.createReader(inputStream);
        return Response.ok(jsonReader.readObject()).header("Access-Control-Allow-Origin", "*").build();
    }
share

I got this error with $http.get in angular. I needed to use $http.jsonp instead.

share

You can bypass the problem by using YQL to proxy the request through Yahoos servers. Just a few lines of code.

var yql_url = 'https://query.yahooapis.com/v1/public/yql';
var url = 'your api url';

$.ajax({
'url': yql_url,
'data': {
'q': 'SELECT * FROM json WHERE url="'+url+'"',
'format': 'json',
'jsonCompat': 'new',
 },
'dataType': 'jsonp',
'success': function(response) {
 console.log(response);
},
});

Here's the link with an explanation: https://vverma.net/fetch-any-json-using-jsonp-and-yql.html

share

CORS is for you. CORS is "Cross Origin Resource Sharing", is a way to send 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 how to choice, I think you need a full functional component to do that.Let me introduce a simple component catta


If you are using modern browser (> IE9, Chrome, FF, Edge, etc.), Very Recommend you to use a simple but beauty component https://github.com/Joker-Jelly/catta.It have no dependence, Less than 3KB, and it support Fetch, AJAX and JSONP with same deadly sample syntax and options.

catta('./data/simple.json').then(function (res) {
  console.log(res);
});

It also it support all the way to import to your project, like ES6 module, CommonJS and even <script> in HTML.

share
    
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/… – Si8 Mar 24 at 14:12

https://github.com/Rob--W/cors-anywhere/ provides (NodeJS) 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.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS has details to explain how browsers handle cross-origin requests that client-side web applications make from JavaScript and what headers you must configure sending of by the server the request is made to, if you can.

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 mentioned in other comments here, there are good reasons for not trusting an open proxy with your requests. That said, if you know what you’re doing and you decide an open proxy works for your needs, https://cors-anywhere.herokuapp.com/ is one that’s reliably available, actively maintained, and that runs an instance of the https://github.com/Rob--W/cors-anywhere/ code.

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.

share

I have resolve this by enable CORS for client url accessing the web api and it worked successfully. e.g [EnableCors(origins: "http://clientaccessingapi.com", headers: "", methods: "")] :)

share

Please add dataType: 'jsonp' in the Ajax function and it works. (:


    $.ajax({
      type: "POST",
      dataType: 'jsonp',
      success: function(response) {
        alert("success");
      },
      error: function(response) {
        console.log(JSON.stringify(response));
      }
    });

share
    
Doesn't work for Chrome – Omar Khazamov 1 hour ago

For opera (it works the same as chrome), I started browser with this command:

opera --user-data-dir="~/Downloads/opera-session" --disable-web-security

Problem is solved! Now I can work on local html file (in my harddisk) and call ajax requests to remote origins in the same file.

Note-1: You can give any folder in your home directory as --user-data-dir.

Note-2: Tested on debian 8/opera 39

Here is a screenhost.

When you start normally (without the parameters above), the same request falls into error code block.

share

I tried the following solution. This method work only when your server is running locally.

  1. Put following line in file web.xml.

    <filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  2. Download cors-filter-2.1.2 and java-property-utils-1.9.1 and put in library
  3. Open a browser to allow access control with following code in terminal (Mac)

    /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files
    
share

protected by Community Apr 17 '15 at 16:02

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

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.