How to enable CORS in flask How to enable CORS in flask flask flask

How to enable CORS in flask


Here is what worked for me when I deployed to Heroku.

http://flask-cors.readthedocs.org/en/latest/
Install flask-cors by running -pip install -U flask-cors

from flask import Flaskfrom flask_cors import CORS, cross_originapp = Flask(__name__)cors = CORS(app)app.config['CORS_HEADERS'] = 'Content-Type'@app.route("/")@cross_origin()def helloWorld():  return "Hello, cross-origin-world!"


OK, I don't think the official snippet mentioned by galuszkak should be used everywhere, we should concern the case that some bug may be triggered during the handler such as hello_world function. Whether the response is correct or uncorrect, the Access-Control-Allow-Origin header is what we should concern. So, thing is very simple, just like bellow:

@blueprint.after_request # blueprint can also be app~~def after_request(response):    header = response.headers    header['Access-Control-Allow-Origin'] = '*'    return response

That is all~~


I've just faced the same issue and I came to believe that the other answers are a bit more complicated than they need to be, so here's my approach for those who don't want to rely on more libraries or decorators:

A CORS request actually consists of two HTTP requests. A preflight request and then an actual request that is only made if the preflight passes successfully.

The preflight request

Before the actual cross domain POST request, the browser will issue an OPTIONS request. This response should not return any body, but only some reassuring headers telling the browser that it's alright to do this cross-domain request and it's not part of some cross site scripting attack.

I wrote a Python function to build this response using the make_response function from the flask module.

def _build_cors_preflight_response():    response = make_response()    response.headers.add("Access-Control-Allow-Origin", "*")    response.headers.add("Access-Control-Allow-Headers", "*")    response.headers.add("Access-Control-Allow-Methods", "*")    return response

This response is a wildcard one that works for all requests. If you want the additional security gained by CORS, you have to provide a whitelist of origins, headers and methods.

This response will convince your (Chrome) browser to go ahead and do the actual request.

The actual request

When serving the actual request you have to add one CORS header - otherwise the browser won't return the response to the invoking JavaScript code. Instead the request will fail on the client-side. Example with jsonify

response = jsonify({"order_id": 123, "status": "shipped"}response.headers.add("Access-Control-Allow-Origin", "*")return response

I also wrote a function for that.

def _corsify_actual_response(response):    response.headers.add("Access-Control-Allow-Origin", "*")    return response

allowing you to return a one-liner.

Final code

from flask import Flask, request, jsonify, make_responsefrom models import OrderModelflask_app = Flask(__name__)@flask_app.route("/api/orders", methods=["POST", "OPTIONS"])def api_create_order():    if request.method == "OPTIONS": # CORS preflight        return _build_cors_preflight_response()    elif request.method == "POST": # The actual request following the preflight        order = OrderModel.create(...) # Whatever.        return _corsify_actual_response(jsonify(order.to_dict()))    else        raise RuntimeError("Weird - don't know how to handle method {}".format(request.method))def _build_cors_preflight_response():    response = make_response()    response.headers.add("Access-Control-Allow-Origin", "*")    response.headers.add('Access-Control-Allow-Headers', "*")    response.headers.add('Access-Control-Allow-Methods', "*")    return responsedef _corsify_actual_response(response):    response.headers.add("Access-Control-Allow-Origin", "*")    return response