Enabling CORS in Flask

When you’re building a full-stack app with a separate frontend and a Flask backend, the browser’s Same-Origin Policy will block your API calls unless you explicitly allow them. Cross-Origin Resource Sharing (CORS) is the protocol that lets you opt-in. In this guide we will cover two common ways to get it done in Flask. Adding CORS headers manually Flask lets you set response headers directly, so you can choose which endpoints get which CORS rules. Basic allow-origin If your frontend lives at https://myapp.com, you can allow it like this: from flask import Flask, request, jsonify, make_response app = Flask(__name__) @app.route("/api/hello") def hello(): resp = make_response(jsonify({"msg": "hi"})) # allow just one origin resp.headers["Access-Control-Allow-Origin"] = "https://myapp.com" return resp Handling the pre-flight (OPTIONS) request Whenever the browser thinks the real call might be “unsafe” (custom headers, non-GET method, etc.) it sends an OPTIONS probe first. You have to answer it with the correct headers: @app.route("/api/hello", methods=["OPTIONS", "GET", "POST"]) def hello(): if request.method == "OPTIONS": resp = make_response() resp.headers.update({ "Access-Control-Allow-Origin": "https://myapp.com", "Access-Control-Allow-Methods": "GET, POST", "Access-Control-Allow-Headers": "Content-Type, X-Custom", "Access-Control-Allow-Credentials": "true", # only if you need cookies / auth }) resp.status_code = 204 return resp # Normal GET/POST handler if request.method == "GET": resp = make_response(jsonify({"msg": "hi"})) elif request.method == "POST": data = request.get_json() resp = make_response(jsonify({"data": data})) # allow CORS for actual response resp.headers.update({ "Access-Control-Allow-Origin": "https://myapp.com", "Access-Control-Allow-Credentials": "true" }) return resp Manual is great when you need per-endpoint logic (e.g., allow some origins only for certain users), but it gets repetitive fast. Using the flask-cors library The flask-cors library will handle the header logic for you. pip install flask-cors Global configuration (one-liner) from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app, origins=["https://myapp.com"], supports_credentials=True) Now every route responds with the right CORS headers and the pre-flight dance “just works.” Fine-grained control You can apply it to a specific blueprint or route instead: from flask_cors import cross_origin @app.route("/public") @cross_origin() # allow all origins def public_stuff(): ... @app.route("/private") @cross_origin(origins="https://myapp.com", methods=["GET", "POST"], expose_headers=["X-Total-Count"]) def private_stuff(): ... Key options you’ll use most: Option What it does origins Accept single origin, list, or "*" methods Restrict allowed verbs allow_headers Extra request headers you expect expose_headers Response headers the browser can read supports_credentials true → cookies/auth tokens allowed Conclusion To enable CORS in your Flask project, either manually add CORS headers to specific endpoints, or use a third-party library like flask-cors to manage CORS more easily. Either way, both options will allow you to build a robust full-stack application.

May 22, 2025 - 18:20
 0
Enabling CORS in Flask

When you’re building a full-stack app with a separate frontend and a Flask backend, the browser’s Same-Origin Policy will block your API calls unless you explicitly allow them. Cross-Origin Resource Sharing (CORS) is the protocol that lets you opt-in. In this guide we will cover two common ways to get it done in Flask.

Adding CORS headers manually

Flask lets you set response headers directly, so you can choose which endpoints get which CORS rules.

Basic allow-origin

If your frontend lives at https://myapp.com, you can allow it like this:

from flask import Flask, request, jsonify, make_response

app = Flask(__name__)

@app.route("/api/hello")
def hello():
    resp = make_response(jsonify({"msg": "hi"}))
    # allow just one origin
    resp.headers["Access-Control-Allow-Origin"] = "https://myapp.com"
    return resp

Handling the pre-flight (OPTIONS) request

Whenever the browser thinks the real call might be “unsafe” (custom headers, non-GET method, etc.) it sends an OPTIONS probe first. You have to answer it with the correct headers:

@app.route("/api/hello", methods=["OPTIONS", "GET", "POST"])
def hello():
    if request.method == "OPTIONS":
        resp = make_response()
        resp.headers.update({
            "Access-Control-Allow-Origin": "https://myapp.com",
            "Access-Control-Allow-Methods": "GET, POST",
            "Access-Control-Allow-Headers": "Content-Type, X-Custom",
            "Access-Control-Allow-Credentials": "true",  # only if you need cookies / auth
        })
        resp.status_code = 204
        return resp

    # Normal GET/POST handler
    if request.method == "GET":
        resp = make_response(jsonify({"msg": "hi"}))
    elif request.method == "POST":
        data = request.get_json()
        resp = make_response(jsonify({"data": data}))
    # allow CORS for actual response
    resp.headers.update({
        "Access-Control-Allow-Origin": "https://myapp.com",
        "Access-Control-Allow-Credentials": "true"
    })
    return resp

Manual is great when you need per-endpoint logic (e.g., allow some origins only for certain users), but it gets repetitive fast.

Using the flask-cors library

The flask-cors library will handle the header logic for you.

pip install flask-cors

Global configuration (one-liner)

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app, origins=["https://myapp.com"], supports_credentials=True)

Now every route responds with the right CORS headers and the pre-flight dance “just works.”

Fine-grained control

You can apply it to a specific blueprint or route instead:

from flask_cors import cross_origin

@app.route("/public")
@cross_origin()                      # allow all origins
def public_stuff():
    ...

@app.route("/private")
@cross_origin(origins="https://myapp.com",
              methods=["GET", "POST"],
              expose_headers=["X-Total-Count"])
def private_stuff():
    ...

Key options you’ll use most:

Option What it does
origins Accept single origin, list, or "*"
methods Restrict allowed verbs
allow_headers Extra request headers you expect
expose_headers Response headers the browser can read
supports_credentials true → cookies/auth tokens allowed

Conclusion

To enable CORS in your Flask project, either manually add CORS headers to specific endpoints, or use a third-party library like flask-cors to manage CORS more easily. Either way, both options will allow you to build a robust full-stack application.