CodeNewbie Community 🌱

Brandon Redmond
Brandon Redmond

Posted on

No Access-Control-Allow-Origin' header..

Hi all,

I created a very basic app just to try and test out authentication.

I am using flask on the back end, and React on the front end.

When I make the request through the firefox browser, it works (most of the time!). But it does not from chrome.

I get the following message:

Access to fetch at 'http://localhost:5000/api/v1/register' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

If I submit a request via Postman or Curl, it works just fine. So I feel that the backend server code is working fine.

I have tried both including and excluding the headers for 'Access-Control-Allow-Origin' and 'Content-Type'. In all scenarios it doesn't work.

When I googled what to fix, I get a complicated answer like I need to set up a Nginx proxy server.

I am just trying to build apps for my portfolio.

Thank you so much!

Top comments (4)

Collapse
 
djuber profile image
Daniel Uber • Edited

When you test the request with curl (and use -v or -I to show the response headers) - are you seeing the Access-Control-Allow-Origin header in the api response? One complication, and a reason that adding the header to the response might not have work correctly the first time doing the obvious thing, is that Chrome is sending an HTTP OPTIONS request, rather than a GET to your route, and it's checking the headers there (if it only checked the response headers after sending the first request, that would defeat the purpose of the cross origin protection, only blocking subsequent follow-up requests, but letting the first one through). If you are only setting the cors header in your app's defined routes for the GET/POST requests, rather than globally, that can cause your local curl/postman tests to succeed since they aren't checking CORS, but your browser requests to fail (chrome will check).

A test like this would make the most sense to confirm you are seeing the header you expect:

# the GET request your browser is asking for:
curl -I http://localhost:5000/api/v1/register

# preflight check is an OPTIONS request, not GET, 
# chrome sends this first, then the GET
curl -I -X OPTIONS http://localhost:5000/api/v1/register
Enter fullscreen mode Exit fullscreen mode

In a quick sample test (I tried the simplest xhr request example from a browser to confirm), the flask-cors module looks like it added the headers to all responses from the app (not just specific routes). Effectively this was what I did to get both the options and the get requests to return the correct header:

# you probably import flask or parts of it, add flask_cors next
from flask_cors import CORS, cross_origin

# create the server app, you likely have something like this
app = Flask(__name__) 

# attach the CORS wrapper to the app
CORS(app, supports_credentials=True) 

# the rest of your flask code, like @app.route(...)
Enter fullscreen mode Exit fullscreen mode

When I added that it changed the response headers from the base

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 22
Server: Werkzeug/2.0.3 Python/3.9.2
Date: Mon, 07 Feb 2022 23:38:37 GMT
Enter fullscreen mode Exit fullscreen mode

To a slightly more useful case

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 22
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.3 Python/3.9.2
Date: Mon, 07 Feb 2022 23:40:20 GMT
Enter fullscreen mode Exit fullscreen mode

The options response looked like this (there's no body in the options response, so you only get headers):

HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: GET, HEAD, OPTIONS
Access-Control-Allow-Origin: *
Content-Length: 0
Server: Werkzeug/2.0.3 Python/3.9.2
Date: Mon, 07 Feb 2022 23:49:22 GMT
Enter fullscreen mode Exit fullscreen mode

Hope this helps.

Collapse
 
rohit1101 profile image
rohit1101

@bredmond1019 The reason why you get a response from postman but not in the browser is because CORS is a browser implementation(feature) to prevent cross site access.

The browser checkers for the header
Access-control-allow-origin from the api response if the header is not present in the response header browser throws an CORS error.

Hence we have to the header for the required cross-site

Here for example:

Access-control-allow-origin: localhost/5000

Please read this: developer.mozilla.org/en-US/docs/W... how many ever times you want it’s gold.

Collapse
 
rushvulture profile image
rushvulture

Chrome is sending an HTTP OPTIONS request, rather than a GET to your route, and it's checking the headers there. This is a complication, and it's a reason that adding the header to the response might not have worked correctly the first time doing the obvious thing. Adding the header to the response is the obvious thing to do.
More information developer.mozilla.org/en-US/docs/W... penalty kick online API response includes access-control-allow-origin header information In the event that the header is missing from the response header, the browser will generate a CORS error.

Collapse
 
bethany23842289 profile image
Bethany Roberts

Thanks