Categories
cors flask-restless javascript jquery same-origin-policy

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

3068

Mod note: This question is about why XMLHttpRequest/fetch/etc. on the browser are subject to the Same Access Policy restrictions (you get errors mentioning CORB or CORS) while Postman is not. This question is not about how to fix a “No ‘Access-Control-Allow-Origin’…” error. It’s about why they happen.

Please stop posting:


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

5

1580

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.

2

  • 225

    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.

    Nov 17, 2013 at 20:01


  • 19

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

    Nov 17, 2013 at 20:08

333

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("https://stackoverflow.com/")
def helloWorld():
  return "Hello, cross-origin-world!"

For more details, you can check the Flask documentation.

9

  • 217

    You shouldn’t turn off CORS because you don’t know what its for. This leaves your users in a fundamentally unsafe state.

    – user229044

    Dec 30, 2014 at 6:12


  • 166

    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.

    – ZurabWeb

    Feb 26, 2015 at 16:37


  • 3

    @meagar Agreeing with you that we shouldn’t turn of CORS but at times we need to test the application while developing it and for that, the easiest way is to turn of CORS and check if everything works fine. Many times frontend devs don’t have access to the backend system where they can change things or they need to write a proxy for the same. The best way to add a chrome extension that turns off CORS for development purposes, as written in the answer which is deleted.

    – shruti

    Sep 29, 2021 at 15:05

  • It should be much helpful if the answer (or the edit with the WARNING on top) would explain to whom is risky if using that header() script in php. The question here is about a foreign site where we have no control, and that only allows us to navigate and see it from a browser, while if we need to access the resources from our server instead it launches the CORS protection (to not let us make too much inquiries per second). Therefore, my question still stands, what dangers do we visitors have if using in OUR server that header() script ?? Did the editor confused the visitor (us) with the host?

    – Eve

    Nov 30, 2021 at 21:37

  • @Eve CORS protection isn’t about the number of inquiries per second! It rejects any other website to use your resource service or page. The warning already contains two links to explain what risks are

    Dec 3, 2021 at 12:37


97

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

0