By Mr Jedi


2013-11-17 19:29:06 8 Comments

Mod note: This question is about why Postman is not subject to CORS restrictions in the same way an XMLHttpRequest is. This question is not about how to fix a "No 'Access-Control-Allow-Origin'..." error.

Please stop posting:

  • CORS configurations for every language/framework under the sun. Instead find your relevant language/framework's question.
  • 3rd party services that allow a request to circumvent CORS
  • Command line options for turning off CORS for various browsers

I am trying to do authorization using JavaScript by connecting to the RESTful API built-in Flask. However, when I make the request, I get the following error:

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 made the request via 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);
    });

9 comments

@Adwaith 2020-07-21 17:06:46

If you want to bypass that restriction when fetching the contents with fetch API or XMLHttpRequest in javascript, you can use a proxy server so that it sets the header Access-Control-Allow-Origin to *.

const express = require('express');
const request = require('request');

const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});

app.get('/fetch', (req, res) => {
  request(
    { url: req.query.url },
    (error, response, body) => {
      if (error || response.statusCode !== 200) {
        return res.status(500).send('error');
      }
      res.send(body);
    }
  )
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));

Above is a sample code( node Js required ) which can act as a proxy server. For eg: If I want to fetch https://www.google.com normally a CORS error is thrown, but now since the request is sent through the proxy server hosted locally at port 3000, the proxy server adds the Access-Control-Allow-Origin header in the response and there wont be any issue.

Send a GET request to http://localhost:3000/fetch?url=Your URL here , instead of directly sending the request to the URl you want to fetch.

Your URL here stands for the URL you wish to fetch eg: https://www.google.com

@Kms 2020-03-10 17:34:03

Encountered the same error in different use case.

Use Case: In chrome when tried to call Spring REST end point in angular.

enter image description here

Solution: Add @CrossOrigin("*") annotation on top of respective Controller Class.

enter image description here

@neo7bf 2020-05-20 16:10:24

I use localhost instead of * for security

@George Livingston 2016-12-13 13:02:58

Because
$.ajax({type: "POST" - calls OPTIONS
$.post( - Calls POST

Both are different. Postman calls "POST" properly, but when we call it, it will be "OPTIONS".

For C# web services - Web API

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");
    }
});

Note: If you are looking for downloading content from a third-party website then this will not help you. You can try the following code, but not JavaScript.

System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");

@Andre Mesquita 2017-05-22 13:41:53

This config solved same error on Wordpress at Azure Services. Thanks.

@pechar 2017-06-09 08:30:06

I would suggest using a specific origin value to avoid requests from external domains. So for example instead of * use https://www.myotherdomain.com

@Peter Mortensen 2020-01-27 02:52:25

@Shakti Srivastav 2020-04-18 16:12:07

Only for .NET Core Web API project, add following changes:

  1. Add the following code after the services.AddMvc() line in the ConfigureServices() method of the Startup.cs file:
services.AddCors(allowsites=>{allowsites.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
            });
  1. Add the following code after app.UseMvc() line in the Configure() method of the Startup.cs file:
app.UseCors(options => options.AllowAnyOrigin());
  1. Open the controller which you want to access outside the domain and add this following attribute at the controller level:
[EnableCors("AllowOrigin")]

@Sai Vaibhav Medavarapu 2020-03-09 17:08:51

If you use .NET as your middle tier, check the route attribute clearly, for example,

I had issue when it was like this,

[Route("something/{somethingLong: long}")] //Space.

Fixed it by this,

[Route("something/{somethingLong:long}")] //No space

@Gopinath 2020-02-02 10:27:43

Applying a CORS restriction is a security feature defined by a server and implemented by a browser.

The browser looks at the CORS policy of the server and respects it.

However, the Postman tool does not bother about the CORS policy of the server.

That is why the CORS error appears in the browser, but not in Postman.

@Christopher Bonitz 2020-04-24 08:00:25

Yes, I cannot stress out enough why this little detail deserves some attention. When talking security its paramount to mention that CORS is only as strong as the client implementing it. So imagine you take a simple HttpClient (server-side code) and build a proxy, whom then does your requests... The security can be completely circumvented, really leaving the CORS standard as a poor solution

@Shady Mohamed Sherif 2014-12-03 20:24:24

WARNING: Using Access-Control-Allow-Origin: * can make your API/website vulnerable to cross-site request forgery (CSRF) attacks. Make certain you understand the risks before using this code.

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: *'); ?>

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"
},

If you are using Flask same as the question; you have first to install flask-cors

$ pip install -U flask-cors

Then include the Flask cors in your application.

from flask_cors import CORS

A simple application will look like:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

For more details, you can check the Flask documentation.

@llazzaro 2014-12-20 19:25:19

and it's not secure

@Shady Mohamed Sherif 2014-12-28 07:24:30

Yes I know it is about Js, But I solved it using the PHP very easily! About the security issue if JS is currently on another domain, you can go through the JS to allow its cross origin why you didn't find that isn't secure?

@user229044 2014-12-30 06:12:55

You shouldn't turn off CORS because you don't know what its for. This is a terrible answer.

@ZurabWeb 2015-02-26 16:37:57

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.

@Saurin Dashadia 2015-03-02 06:59:17

I had the same issue on same domain as I have full site using https but only one page is using http method and any request from http page results in same error. I wanted to solve it with JS only as adding such header wasnt my first choice. I have tried all above solutions like placing crossDomain:true, withCredentials: true and also followed CORS but no solution worked ever. Then finaly I have added header('Access-Control-Allow-Origin: *');

@Saurin Dashadia 2015-03-02 07:00:09

One thing I would like to add here is. If you are using header('Access-Control-Allow-Origin: *'); you need to remove withCredentials: true from ajax request.

@Thomas F. 2015-10-15 14:55:13

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.

@Divyesh Kanzariya 2016-04-28 05:48:46

@shadysherif how to same things using JavaScript any idea ??

@Pradeep Srivastava 2017-02-09 06:30:45

@shadysherif It worked it can be use in non-transaction data procession comes in handy nice!!

@Epirocks 2017-02-27 17:38:54

Noone cares about security when developing locally, CORS just gets in the way. You might have a node.js server running on a different port/server than the one you are requesting data from. But in production they may all run off the same server in which case CORS doesn't cause a problem.

@Ari Waisberg 2017-03-17 19:38:18

I like this answer... I have the same issue and it solves it... He explained there are some security issues, but that's another problem and let everyone individualy think and resolve that issue...

@Chuck Le Butt 2019-05-11 17:54:23

This is a perfect answer if you DO know what you're doing (ie. testing locally). Thanks

@Kamil Kiełczewski 2019-12-16 09:06:06

In the below investigation as API, I use http://example.com instead of http://myApiUrl/login from your question, because this first one working.

I assume that your page is on http://my-site.local:8088.

The reason why you see different results is that Postman:

  • set header Host=example.com (your API)
  • NOT set header Origin

This is similar to browsers' way of sending requests when the site and API has the same domain (browsers also set the header item Referer=http://my-site.local:8088, however I don't see it in Postman). When Origin header is not set, usually servers allow such requests by default.

Enter image description here

This is the standard way how Postman sends requests. But a browser sends requests differently when your site and API have different domains, and then CORS occurs and the browser automatically:

  • sets header Host=example.com (yours as API)
  • sets header Origin=http://my-site.local:8088 (your site)

(The header Referer has the same value as Origin). And now in Chrome's Console & Networks tab you will see:

Enter image description here

Enter image description here

When you have Host != Origin this is CORS, and when the server detects such a request, it usually blocks it by default.

Origin=null is set when you open HTML content from a local directory, and it sends a request. The same situation is when you send a request inside an <iframe>, like in the below snippet (but here the Host header is not set at all) - in general, everywhere the HTML specification says opaque origin, you can translate that to Origin=null. More information about this you can find here.

fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab

If you do not use a simple CORS request, usually the browser automatically also sends an OPTIONS request before sending the main request - more information is here. The snippet below shows it:

fetch('http://example.com/api', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json'}
});
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)

You can change the configuration of your server to allow CORS requests.

Here is an example configuration which turns on CORS on nginx (nginx.conf file) - be very careful with setting always/"$http_origin" for nginx and "*" for Apache - this will unblock CORS from any domain.

location ~ ^/index\.php(/|$) {
   ...
    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    if ($request_method = OPTIONS) {
        add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        return 204;
    }
}

Here is an example configuration which turns on CORS on Apache (.htaccess file)

# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests                                                 |
# ------------------------------------------------------------------------------

# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/

# <IfModule mod_headers.c>
#    Header set Access-Control-Allow-Origin "*"
# </IfModule>

# Header set Header set Access-Control-Allow-Origin "*"
# Header always set Access-Control-Allow-Credentials "true"

Access-Control-Allow-Origin "http://your-page.com:80"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"

@MD. Sahib Bin Mahboob 2013-11-17 19:49:53

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.

@Mr Jedi 2013-11-17 19:54:44

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?

@Ray Nicholus 2013-11-17 20:01:25

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 2013-11-17 20:08:48

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

@sideshowbarker 2020-08-20 01:06:18

For a solution that’ll allow your frontend JavaScript code to access a “blocked” response, see the How to use a CORS proxy to get around “No Access-Control-Allow-Origin header” problems section of the answer at stackoverflow.com/a/43881141/441757

Related Questions

Sponsored Content

13 Answered Questions

[SOLVED] No 'Access-Control-Allow-Origin' - Node / Apache Port Issue

9 Answered Questions

[SOLVED] XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header

21 Answered Questions

[SOLVED] Response to preflight request doesn't pass access control check

19 Answered Questions

10 Answered Questions

16 Answered Questions

[SOLVED] How does Access-Control-Allow-Origin header work?

31 Answered Questions

[SOLVED] Access-Control-Allow-Origin Multiple Origin Domains?

Sponsored Content