[javascript] Why does my JavaScript code receive a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, while Postman does not?

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

The answer is


The error you get is due to the CORS standard, which sets some restrictions on how JavaScript can perform ajax requests.

The CORS standard is a client-side standard, implemented in the browser. So it is the browser which prevent the call from completing and generates the error message - not the server.

Postman does not implement the CORS restrictions, which is why you don't see the same error when making the same call from Postman.


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.

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

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:

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

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.

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

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

_x000D_
_x000D_
# ------------------------------------------------------------------------------_x000D_
# | Cross-domain Ajax requests                                                 |_x000D_
# ------------------------------------------------------------------------------_x000D_
_x000D_
# Enable cross-origin Ajax requests._x000D_
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity_x000D_
# http://enable-cors.org/_x000D_
_x000D_
# <IfModule mod_headers.c>_x000D_
#    Header set Access-Control-Allow-Origin "*"_x000D_
# </IfModule>_x000D_
_x000D_
# Header set Header set Access-Control-Allow-Origin "*"_x000D_
# Header always set Access-Control-Allow-Credentials "true"_x000D_
_x000D_
Access-Control-Allow-Origin "http://your-page.com:80"_x000D_
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"_x000D_
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
_x000D_
_x000D_
_x000D_


Are you using Webfonts from Google, Typekit, etc? There are multiple ways you could use Webfonts like @font-face or CSS3 methods, some browsers like Firefox & IE may refuse to embed the font when it’s coming from some non-standard 3rd party URL (like your blog) for same security reason.

In order to fix an issue for your WordPress blog, just put below into your .htaccess file.

<IfModule mod_headers.c>
  <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
  Header set Access-Control-Allow-Origin "*"
  </FilesMatch>
</IfModule>

Source : https://crunchify.com/how-to-fix-access-control-allow-origin-issue-for-your-https-enabled-wordpress-site-and-maxcdn/


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


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


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.


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.


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

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")]

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

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to cors

Axios having CORS issue Cross-Origin Read Blocking (CORB) Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource How to allow CORS in react.js? Set cookies for cross origin requests XMLHttpRequest blocked by CORS Policy How to enable CORS in ASP.net Core WebAPI No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API How to overcome the CORS issue in ReactJS Trying to use fetch and pass in mode: no-cors

Examples related to same-origin-policy

XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header Disable-web-security in Chrome 48+ How to enable CORS on Firefox? SecurityError: Blocked a frame with origin from accessing a cross-origin frame Why does my JavaScript code receive a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, while Postman does not? Disable firefox same origin policy Catch error if iframe src fails to load . Error :-"Refused to display 'http://www.google.co.in/' in a frame.." Cross Domain Form POSTing How do I use Access-Control-Allow-Origin? Does it just go in between the html head tags? Disabling same-origin policy in Safari

Examples related to flask-restless

Why does my JavaScript code receive a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, while Postman does not?