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.

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.