Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting CORS preflight error even with flask cors initialized #292

Open
ryanbrwr opened this issue Mar 30, 2021 · 26 comments
Open

Getting CORS preflight error even with flask cors initialized #292

ryanbrwr opened this issue Mar 30, 2021 · 26 comments

Comments

@ryanbrwr
Copy link

ryanbrwr commented Mar 30, 2021

Hey guys, I've been trying to get flask_cors to work for over two weeks now, so thought that I would write an issue.

Here's what is in the init.py file

app = Flask(__name__, static_url_path='/static')
app.config.from_pyfile('config.py')

cors = CORS(resources={
    r'/*': {
        'origins': [
            'http://localhost:8080'
        ]
    }
})

cors.init_app(app)

The error that I'm getting is:

login?redirectNotebook=rose.intro:1 Access to XMLHttpRequest at 'http://localhost:5000/users' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

Went into the library to poke around and it looks like the after request isn't being called. The backend is running on localhost:5000 and the frontend is running on localhost:8080, any help would be greatly appreciated!

@shrhawk-entertainer
Copy link

@ryanbrwr did you find any solution?

@ryanbrwr
Copy link
Author

@shrhawk-entertainer No unfortunately I never found a solution and I am currently having to develop with CORS disabled in safari to get around this.

@CrafterSvK
Copy link

@ryanbrwr Does your OPTIONS call to server return 200 OK?

@ryanbrwr
Copy link
Author

I gave up a long time ago and used a different lib, appreciate it though.

@MeyerMathieu
Copy link

@ryanbrwr what lib did you used ?
I am facing a similiar problem 😕

@cohi-dev
Copy link

@Elynad did you implement the app.before_request hook ?

@MeyerMathieu
Copy link

MeyerMathieu commented Jul 17, 2021

@cohi-dev Yes, I did

Here is a part of my code :

from flask import Flask
from flask_cors import CORS
from typing import List, Dict
import mysql.connector
import json

app = Flask(__name__)
CORS(app)

[...]

@app.after_request
def add_header(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response

@app.route('/')
def hello() :
    return 'This is a test to check if the api is working.'

I also tried to replace CORS(app) with cors = CORS(app, resources={r"/*": {"origins": "*"}})

And I also tried to add @cross_origin() under each @app.route([...])

The thing is, everything is working fine in local (I am using dockers), but when these dockers are deployed on AWS EC2 instance, I get an XMLHttpRequest error 😕

@CrafterSvK
Copy link

Check network tab in browser and check preflight response paste it here.

@MeyerMathieu
Copy link

Screenshot 2021-07-20 at 18 58 34

I did not manage to copy it, but here you go

I just replaced "localhost" API address with "127.0.0.1", and I get the same result

@shrhawk-entertainer
Copy link

@Elynad what I did is

from flask import Response

@current_app.before_request
def basic_authentication():
    if request.method.lower() == 'options':
        return Response()

@MeyerMathieu
Copy link

@shrhawk-entertainer It seems to be a good answer, but where do you get request from ?

@CrafterSvK
Copy link

@shrhawk-entertainer It seems to be a good answer, but where do you get request from ?

You import it from flask module. Check documentation on how it works if you want to know how it works.

@MeyerMathieu
Copy link

Right.
I added from flask import request.

Does not seems to work, I will make some tests this friday to keep you in touch

@CrafterSvK
Copy link

CrafterSvK commented Jul 21, 2021

What do you mean by does not work. Do you have it registered in right blueprint. Have you tried breakpoint in that before request? Preflight request must return correct headers and respond with status 200.

@MeyerMathieu
Copy link

MeyerMathieu commented Jul 23, 2021

Preflight request did return status 200.

But the original request does not seems to work, and I get nothing in the "Response" tab when I click on the request.

Screenshot 2021-07-23 at 07 23 33

As I am testing a production deployment, I can't breakpoint, but I am writing in a log.txt file :

@app.before_request
def basic_authentication():
    file = open("log.txt", "w")
    file = open("log.txt", "a")
    file.write("In basic_authentication")
    if request.method.lower() == 'options':
        file.write("In basic_authentication ; returning Response()")
        return Response()

The log.txt file is not created, I suppose I am not even going in basic_authentication() function.

@shuttle1987
Copy link

@Elynad I'd suggest that you use the logging functionality provided by flask to do this logging.

@overbid
Copy link

overbid commented Jan 17, 2022

I think the best way to avoid this issue is add more rule for url like.

from werkzeug.routing import Rule

app = Flask(__name__, static_url_path='/static')
app.url_rule_class = lambda path, **options: Rule(
    app.static_url_path + path, **options
)

@FLAGLORD
Copy link

Did someone find some solution? It really sucks.....

@echoboomer
Copy link

Did someone find some solution? It really sucks.....

This worked brilliantly for me: #292 (comment)

@joaodlf
Copy link

joaodlf commented Jun 24, 2022

from flask import Response

@current_app.before_request
def basic_authentication():
if request.method.lower() == 'options':
return Response()

Wow. This works for me too. Effectively returning a 200 on OPTIONS requests (pre flight).

My app has no issues under 127.0.0.1 using this library, but as soon as I switched to localhost, I was hitting this same issue.

Would really like to understand why.

@guruprakashIT
Copy link

@joaodlf

You can use this way. because it's work for me

@app.before_request def before_request(): headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type' } if request.method == 'OPTIONS' or request.method == 'options': return jsonify(headers), 200

it solve the cors issue

@superdev87
Copy link

Did someone find another solution?
I've tried all above, but not working in my side.

@svrakata
Copy link

svrakata commented Nov 9, 2023

For me the problem was in defining endpoints before setting CORS(app). No idea why.

@mahendra-taiyo
Copy link

This before request setup worked for me

@app.before_request
def before_request():
    headers = {'Access-Control-Allow-Origin': '*',
               'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
               'Access-Control-Allow-Headers': 'Content-Type'}
    if request.method.lower() == 'options':
        return jsonify(headers), 200

@alamgiruk7
Copy link

This before request setup worked for me

@app.before_request
def before_request():
    headers = {'Access-Control-Allow-Origin': '*',
               'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
               'Access-Control-Allow-Headers': 'Content-Type'}
    if request.method.lower() == 'options':
        return jsonify(headers), 200

Thanks @mahendra-taiyo, This also worked for me.
Moreover, In my case I figured out that I had used url_prefixes for all the apis which caused redirection and CORS doesn't allow preflight requests or redirects. So removing the url_prefixes while registering blueprints also worked for me But if you don't want to remove the prefixes then go with the above approach as mentioned by @mahendra-taiyo

@mvilrokx
Copy link

Sorry for adding a comment to this long open issue but hopefully this helps other people that end up here looking for a solution to their CORS issue.

I tried all of the above and nothing helped. I finally noticed an error in the browser's console that said:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5001/... (Reason: expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’).

After some reading I realized I need to add this to my code:

CORS(
    app,
    supports_credentials=True, # Add This
    origins=["http://localhost:3000"], # You'll need this, you cannot use * (wildcard domain) when using supports_credentials=True
)

Hopefully this helps out other people.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests