# How to Enable Cross Origin Resource Sharing with Flask-CORS: Complete Implementation Guide

> Easily enable Cross Origin Resource Sharing in Flask with Flask-CORS. This guide provides a complete implementation to add the Access-Control-Allow-Origin header to your responses.

- Repository: [Pallets/flask](https://github.com/pallets/flask)
- Tags: how-to-guide
- Published: 2026-02-13

---

**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`](https://github.com/pallets/flask/blob/main/src/flask/app.py) and the `Response` wrapper in [`src/flask/wrappers.py`](https://github.com/pallets/flask/blob/main/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`](https://github.com/pallets/flask/blob/main/src/flask/blueprints.py).

The request handling pipeline can be extended at two natural hook points where Flask-CORS integrates:

1. **During app creation** – extensions receive the `Flask` instance and can attach themselves to the app’s internal `wsgi_app` stack defined in [`src/flask/app.py`](https://github.com/pallets/flask/blob/main/src/flask/app.py).
2. **After a view returns a response** – extensions may modify the outgoing `Response` object from [`src/flask/wrappers.py`](https://github.com/pallets/flask/blob/main/src/flask/wrappers.py) before 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:

```bash
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:

```python
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:

```python
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`](https://github.com/pallets/flask/blob/main/src/flask/wrappers.py).

### Blueprint-Level CORS Configuration

Flask-CORS integrates with Flask's blueprint system defined in [`src/flask/blueprints.py`](https://github.com/pallets/flask/blob/main/src/flask/blueprints.py) to enable modular CORS policies:

```python
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:

```python
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`](https://github.com/pallets/flask/blob/main/src/flask/wrappers.py).

### Enabling Credentials Support

When sending cookies or HTTP authentication across origins:

```python
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`](https://github.com/pallets/flask/blob/main/src/flask/app.py) and [`src/flask/wrappers.py`](https://github.com/pallets/flask/blob/main/src/flask/wrappers.py) clarifies why the `CORS(app)` pattern works.

**App Initialization Hook**

In [`src/flask/app.py`](https://github.com/pallets/flask/blob/main/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`](https://github.com/pallets/flask/blob/main/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-cors` to 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 `origins` instead of using wildcards, and set `supports_credentials=True` only with explicit origin lists.
- **Customize headers and methods** using `expose_headers`, `allow_headers`, and `methods` parameters to control cross-origin data sharing.
- **Understand the architecture**: Flask-CORS works by wrapping `app.wsgi_app` from [`src/flask/app.py`](https://github.com/pallets/flask/blob/main/src/flask/app.py) and modifying `Response.headers` from [`src/flask/wrappers.py`](https://github.com/pallets/flask/blob/main/src/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.