How to Enable Cross Origin Resource Sharing with Flask-CORS: Complete Implementation Guide
Enable Cross Origin Resource Sharing in Flask by installing the flask-cors package and initializing it with CORS(app) to automatically inject the required Access-Control-Allow-Origin headers into every response.
To enable Cross Origin Resource Sharing with Flask-CORS, you need to understand how Flask's minimal core architecture handles HTTP responses. The pallets/flask repository provides the foundational Flask class in src/flask/app.py and the Response wrapper in src/flask/wrappers.py, but delegates CORS functionality to extensions that hook into the WSGI application stack.
Understanding Flask's Extension Architecture
Flask’s core is deliberately minimal. It provides the Flask class (the central WSGI application object), a request-response cycle built on the Request and Response wrappers, and a blueprint system for modular routing defined in src/flask/blueprints.py.
The request handling pipeline can be extended at two natural hook points where Flask-CORS integrates:
- During app creation – extensions receive the
Flaskinstance and can attach themselves to the app’s internalwsgi_appstack defined insrc/flask/app.py. - After a view returns a response – extensions may modify the outgoing
Responseobject fromsrc/flask/wrappers.pybefore it is sent to the client.
Cross-Origin Resource Sharing is implemented by adding specific HTTP headers (Access-Control-Allow-Origin, Access-Control-Allow-Methods, etc.) to every response. Because Flask does not include this logic itself, the canonical way to enable CORS is to install the Flask-CORS extension, which plugs into the two hook points described above.
Installing Flask-CORS
Install the extension via pip:
pip install flask-cors
This package provides the CORS class that wraps your Flask application to handle pre-flight OPTIONS requests and inject CORS headers into responses.
How to Enable CORS in Flask
Global CORS Enablement
The simplest way to enable Cross Origin Resource Sharing with Flask-CORS is to apply it to your entire application:
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
# Enable CORS for *all* routes and origins
CORS(app)
@app.route("/api/data")
def data():
return jsonify({"msg": "Hello from Flask!"})
if __name__ == "__main__":
app.run()
All routes now automatically include Access-Control-Allow-Origin: * in their response headers.
Restricting Allowed Origins
For security, you should whitelist specific domains rather than allowing all origins:
CORS(app, origins=["https://example.com", "https://sub.example.org"])
Only requests originating from the listed domains will receive the CORS headers. This configuration modifies how the Flask-CORS middleware inspects the Origin header before setting the Access-Control-Allow-Origin response header in the Response object from src/flask/wrappers.py.
Blueprint-Level CORS Configuration
Flask-CORS integrates with Flask's blueprint system defined in src/flask/blueprints.py to enable modular CORS policies:
from flask import Blueprint
from flask_cors import CORS
api_bp = Blueprint("api", __name__, url_prefix="/api")
CORS(api_bp, resources={r"/public/*": {"origins": "*"}})
@api_bp.route("/public/info")
def public_info():
return {"info": "public"}
@api_bp.route("/private/data")
def private_data():
return {"secret": "data"} # No CORS headers here
Only routes matching /api/public/* are exposed to any origin; the private route remains same-origin only. This demonstrates how Flask-CORS applies its middleware wrapper at the blueprint level before the routes are registered with the main Flask app object.
Custom Headers and HTTP Methods
Control which headers are exposed and which methods are allowed:
CORS(
app,
resources={r"/api/*": {"origins": "*"}},
expose_headers=["X-My-Custom-Header"],
allow_headers=["Content-Type", "Authorization"],
methods=["GET", "POST", "DELETE"],
)
expose_headers– tells browsers which response headers the client may read.allow_headers– headers the client is permitted to send in a cross-origin request.methods– limits the HTTP verbs that CORS pre-flight will approve.
These parameters configure the Flask-CORS middleware to set the corresponding Access-Control-Expose-Headers, Access-Control-Allow-Headers, and Access-Control-Allow-Methods headers on the Response object from src/flask/wrappers.py.
Enabling Credentials Support
When sending cookies or HTTP authentication across origins:
CORS(app, supports_credentials=True, origins=["https://trusted.com"])
When supports_credentials=True, Flask-CORS adds Access-Control-Allow-Credentials: true and mirrors the request origin instead of using *. You must specify explicit origins when using credentials; wildcard origins are rejected by browsers when credentials are included.
How Flask-CORS Integrates with Flask Internals
Understanding the integration points in src/flask/app.py and src/flask/wrappers.py clarifies why the CORS(app) pattern works.
App Initialization Hook
In src/flask/app.py, the Flask class creates the WSGI application callable (self.wsgi_app). When you call CORS(app), the extension wraps app.wsgi_app with its own middleware. This middleware intercepts incoming requests before they reach Flask's routing logic in Flask.full_dispatch_request.
Response Processing Hook
After a view function executes, Flask constructs a Response object using the Response class from src/flask/wrappers.py. The CORS middleware then modifies response.headers (a dictionary-like object) to inject the Access-Control-Allow-Origin and related headers before the response is yielded to the WSGI server.
This design keeps CORS handling outside the core Flask code, preserving Flask’s "micro-framework" philosophy while giving developers an easy, well-tested way to support cross-origin browsers.
Summary
- Install the extension with
pip install flask-corsto add CORS functionality without modifying Flask's core. - Initialize globally with
CORS(app)to apply headers to all routes, or apply to specific blueprints for modular security policies. - Configure security by specifying
originsinstead of using wildcards, and setsupports_credentials=Trueonly with explicit origin lists. - Customize headers and methods using
expose_headers,allow_headers, andmethodsparameters to control cross-origin data sharing. - Understand the architecture: Flask-CORS works by wrapping
app.wsgi_appfromsrc/flask/app.pyand modifyingResponse.headersfromsrc/flask/wrappers.py.
Frequently Asked Questions
Do I need to manually handle OPTIONS requests when using Flask-CORS?
No. Flask-CORS automatically intercepts pre-flight OPTIONS requests at the WSGI middleware layer before they reach your view functions. The extension generates the appropriate Access-Control-Allow-Methods and Access-Control-Allow-Headers responses based on your configuration, eliminating the need for manual route definitions for OPTIONS requests.
Can I enable CORS for specific routes only while keeping others same-origin?
Yes. Instead of applying CORS(app) globally, you can pass specific resources patterns or apply CORS to individual blueprints. For example, CORS(app, resources={r"/api/*": {"origins": "*"}}) enables CORS only for routes matching /api/*, while all other routes remain restricted to same-origin requests.
Why am I still seeing CORS errors after installing and configuring Flask-CORS?
CORS errors typically indicate a mismatch between your Flask-CORS configuration and the browser's requirements. Common issues include: using origins="*" with supports_credentials=True (browsers reject wildcard origins when credentials are used), missing allow_headers for custom headers like Authorization, or browser caching of pre-flight responses. Check your browser's developer console for the specific blocked header or origin to adjust your CORS() parameters accordingly.
Is Flask-CORS safe for production environments?
Flask-CORS is safe for production when configured correctly, but security depends on your specific settings. Avoid using origins="*" for API endpoints that handle sensitive data or authentication; instead, explicitly whitelist your frontend domains. When using supports_credentials=True, always specify explicit origins and implement proper authentication checks in your view functions. The extension itself is widely used and maintained, but CORS policies are security mechanisms that must be tailored to your application's threat model.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →