flask-cors
flask-cors copied to clipboard
Getting CORS preflight error even with flask cors initialized
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!
@ryanbrwr did you find any solution?
@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.
@ryanbrwr Does your OPTIONS call to server return 200 OK?
I gave up a long time ago and used a different lib, appreciate it though.
@ryanbrwr what lib did you used ? I am facing a similiar problem 😕
@Elynad did you implement the app.before_request
hook ?
@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 😕
Check network tab in browser and check preflight response paste it here.
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
@Elynad what I did is
from flask import Response
@current_app.before_request
def basic_authentication():
if request.method.lower() == 'options':
return Response()
@shrhawk-entertainer It seems to be a good answer, but where do you get request
from ?
@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.
Right.
I added from flask import request
.
Does not seems to work, I will make some tests this friday to keep you in touch
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.
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.
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.
@Elynad I'd suggest that you use the logging functionality provided by flask to do this logging.
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
)
Did someone find some solution? It really sucks.....
Did someone find some solution? It really sucks.....
This worked brilliantly for me: https://github.com/corydolphin/flask-cors/issues/292#issuecomment-883929183
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.
@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
Did someone find another solution? I've tried all above, but not working in my side.
For me the problem was in defining endpoints before setting CORS(app)
. No idea why.
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