flask-cors icon indicating copy to clipboard operation
flask-cors copied to clipboard

Getting CORS preflight error even with flask cors initialized

Open ryanbrwr opened this issue 3 years ago • 26 comments

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 avatar Mar 30 '21 16:03 ryanbrwr

@ryanbrwr did you find any solution?

shrhawk-entertainer avatar May 19 '21 09:05 shrhawk-entertainer

@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 avatar May 24 '21 02:05 ryanbrwr

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

CrafterSvK avatar Jul 15 '21 16:07 CrafterSvK

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

ryanbrwr avatar Jul 15 '21 22:07 ryanbrwr

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

MeyerMathieu avatar Jul 16 '21 19:07 MeyerMathieu

@Elynad did you implement the app.before_request hook ?

cohi-dev avatar Jul 16 '21 22:07 cohi-dev

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

MeyerMathieu avatar Jul 17 '21 09:07 MeyerMathieu

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

CrafterSvK avatar Jul 17 '21 10:07 CrafterSvK

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

MeyerMathieu avatar Jul 20 '21 17:07 MeyerMathieu

@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 avatar Jul 21 '21 06:07 shrhawk-entertainer

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

MeyerMathieu avatar Jul 21 '21 07:07 MeyerMathieu

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

CrafterSvK avatar Jul 21 '21 07:07 CrafterSvK

Right. I added from flask import request.

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

MeyerMathieu avatar Jul 21 '21 07:07 MeyerMathieu

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.

CrafterSvK avatar Jul 21 '21 07:07 CrafterSvK

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.

MeyerMathieu avatar Jul 23 '21 05:07 MeyerMathieu

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

shuttle1987 avatar Sep 14 '21 13:09 shuttle1987

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
)

overbid avatar Jan 17 '22 02:01 overbid

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

FLAGLORD avatar Jun 16 '22 18:06 FLAGLORD

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

This worked brilliantly for me: https://github.com/corydolphin/flask-cors/issues/292#issuecomment-883929183

echoboomer avatar Jun 20 '22 04:06 echoboomer

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 avatar Jun 24 '22 14:06 joaodlf

@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

guruprakashIT avatar May 23 '23 09:05 guruprakashIT

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

superdev87 avatar Nov 02 '23 07:11 superdev87

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

svrakata avatar Nov 09 '23 18:11 svrakata

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

mahendra-taiyo avatar Mar 29 '24 12:03 mahendra-taiyo