Practical examples of Flask-CORS: Handling Cross-Origin Requests
Let’s skip the abstract talk and go straight into real examples of Flask-CORS: handling cross-origin requests in situations you actually face as a developer. All of these examples build on the same basic pattern: install Flask-CORS, initialize it, then tighten the configuration around your real needs.
pip install flask flask-cors
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # very open config – good for quick experiments only
@app.route("/ping")
def ping():
return jsonify({"status": "ok"})
if __name__ == "__main__":
app.run(debug=True)
This is the classic hello-world example of Flask-CORS: handling cross-origin requests from any domain. It’s fine for a quick prototype, but not something you should ship to production.
Example of Flask-CORS for local React + Flask development
The most common real example of Flask-CORS: handling cross-origin requests is a React frontend on http://localhost:3000 talking to a Flask API on http://127.0.0.1:5000.
Without CORS, your browser blocks these requests. With a targeted Flask-CORS config, you explicitly allow that frontend origin and keep everything else out.
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(
app,
resources={r"/api/*": {"origins": "http://localhost:3000"}},
supports_credentials=False,
)
@app.route("/api/user")
def get_user():
return jsonify({"id": 1, "name": "Jamie"})
if __name__ == "__main__":
app.run(debug=True)
Here, only routes under /api/ are CORS-enabled, and only for your React dev origin. That’s a much safer pattern than spraying CORS(app) across the entire app.
Why this matters in 2024–2025: most teams use separate frontend and backend repos. Local dev almost always involves multiple ports, so a clean, origin-specific configuration like this is now the default pattern for serious projects.
Best examples of Flask-CORS: handling cross-origin requests in production APIs
Development is one thing; production is where misconfigured CORS can turn into a security problem. The best examples of Flask-CORS: handling cross-origin requests in production have a few common traits:
- Only specific trusted domains are allowed
- Only specific HTTP methods are allowed
- Only specific headers are exposed
- Credentials are handled intentionally, not by default
Imagine your production API is at https://api.example.com, and your frontend is at https://app.example.com.
from datetime import timedelta
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(
app,
resources={r"/api/*": {"origins": [
"https://app.example.com",
"https://admin.example.com",
]}},
methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["Content-Type", "Authorization"],
expose_headers=["X-Total-Count"],
max_age=timedelta(hours=1),
)
@app.route("/api/items")
def items():
# # X-Total-Count is visible to the browser because of expose_headers
return ("[]", 200, {"X-Total-Count": "0", "Content-Type": "application/json"})
This example of Flask-CORS configuration shows a production-friendly pattern:
- Multiple specific origins, not
* - Allowed methods limited to what the API actually uses
- Custom headers (
Authorization,X-Total-Count) explicitly wired into CORS max_agecutting down preflight traffic for better performance
If you want to read more about how browsers enforce CORS and preflight behavior, the MDN documentation is still the gold standard: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Examples of Flask-CORS: handling cross-origin requests with credentials (cookies, auth)
As soon as you introduce login sessions, CSRF protection, or cookies, CORS gets more opinionated. Browsers refuse to send credentials across origins unless both sides agree.
Here’s a realistic example of Flask-CORS: handling cross-origin requests for a cookie-based session between:
- Frontend:
https://app.example.com - Backend:
https://api.example.com
from flask import Flask, jsonify, session
from flask_cors import CORS
app = Flask(__name__)
app.secret_key = "change-me" # use a strong secret in real apps
CORS(
app,
resources={r"/api/*": {"origins": "https://app.example.com"}},
supports_credentials=True,
)
@app.route("/api/login")
def login():
session["user_id"] = 1
return jsonify({"logged_in": True})
@app.route("/api/me")
def me():
user_id = session.get("user_id")
if not user_id:
return jsonify({"error": "unauthorized"}), 401
return jsonify({"id": user_id, "name": "Jamie"})
Key points in this example of credentialed CORS:
supports_credentials=Trueis required- The browser must send
withCredentials: trueinfetchor Axios - The
Access-Control-Allow-Originheader cannot be*when credentials are involved
For modern guidance on cookies, sessions, and security headers, the OWASP Cheat Sheet Series is worth bookmarking: https://cheatsheetseries.owasp.org/
Route-level examples of Flask-CORS: handling cross-origin requests selectively
Sometimes you want most of your API locked down, but a few public endpoints need to be called from many origins. That’s where route-level decorators shine.
from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app, resources={r"/api/private/*": {"origins": "https://app.example.com"}})
@app.route("/api/private/data")
def private_data():
return jsonify({"scope": "private"})
@app.route("/api/public/info")
@cross_origin(origins="*")
def public_info():
return jsonify({"status": "public"})
This pattern is one of the best examples of Flask-CORS: handling cross-origin requests at different security levels in the same app. Sensitive APIs stay restricted, while public, cacheable data can be shared more freely.
Real examples of debugging Flask-CORS: when things go wrong
In 2024–2025, the CORS error messages in Chrome, Firefox, and Safari are more explicit than they used to be, but they can still feel cryptic. Here are some real examples of common misconfigurations and how to fix them.
The wildcard + credentials trap
Symptom:
- Error in console:
The value of the 'Access-Control-Allow-Origin' header in the response must not be '*' when the request's credentials mode is 'include'.
Typical bad config:
CORS(app, supports_credentials=True) # origins default to '*'
Fix: specify origins explicitly.
CORS(app, supports_credentials=True, origins=["https://app.example.com"])
The missing preflight (OPTIONS) handler
Symptom:
- Browser sends an OPTIONS request
- Server returns 404 or 405
- Console shows CORS preflight failure
Fix: let Flask-CORS handle OPTIONS automatically (default), or enable it if you disabled it.
CORS(app, automatic_options=True)
And make sure your route decorators allow OPTIONS implicitly, for example by not restricting methods too tightly unless you know what you’re doing.
Mixed HTTP/HTTPS origins
Symptom:
- Works fine in local HTTP
- Fails in production HTTPS, especially with cookies
Fix: align schemes and cookie flags. When you move to HTTPS, set cookies with Secure=True, and make sure your frontend origin in the CORS config also uses https://.
For deeper reading on HTTPS, cookies, and browser security behavior, the US government’s web security guidance is a surprisingly clear resource: https://https.cio.gov/
Examples include Flask-CORS with blueprints and larger apps
Real projects rarely live in a single app.py file. You might be using blueprints, factory patterns, and multiple services. Here’s a slightly larger example of Flask-CORS: handling cross-origin requests in a modular app.
## app/__init__.py
from flask import Flask
from flask_cors import CORS
cors = CORS()
def create_app(config_object=None):
app = Flask(__name__)
if config_object:
app.config.from_object(config_object)
cors.init_app(
app,
resources={
r"/api/public/*": {"origins": "*"},
r"/api/internal/*": {"origins": ["https://app.example.com"]},
},
)
from .public import public_bp
from .internal import internal_bp
app.register_blueprint(public_bp, url_prefix="/api/public")
app.register_blueprint(internal_bp, url_prefix="/api/internal")
return app
## app/public.py
from flask import Blueprint, jsonify
public_bp = Blueprint("public", __name__)
@public_bp.get("/health")
def health():
return jsonify({"status": "ok"})
## app/internal.py
from flask import Blueprint, jsonify
internal_bp = Blueprint("internal", __name__)
@internal_bp.get("/stats")
def stats():
return jsonify({"users": 123})
This structure shows how examples of Flask-CORS: handling cross-origin requests scale up when you have multiple blueprints with different exposure levels.
Modern trends: SPA frontends, mobile apps, and serverless backends
If you’re building in 2024–2025, your Flask API might be talking to:
- A React or Vue SPA hosted on a CDN
- A mobile app using
fetchunder the hood (WebView, React Native, etc.) - A serverless function used as a proxy or aggregation layer
A few modern patterns and examples include:
Static SPA on https://app.example.com + Flask API on https://api.example.com
Use the production-style origin list and credentials pattern from earlier, especially if you’re using OAuth or cookie-based sessions.
Mobile apps
Native mobile apps are not subject to browser CORS in the same way, but if you embed WebViews or run JavaScript in a browser-like environment, you’ll still hit CORS constraints. The same examples of Flask-CORS: handling cross-origin requests apply; the origin might be something like capacitor://localhost or ionic://localhost instead of http://localhost:3000.
Serverless or API gateways
If you front your Flask app with an API gateway (AWS API Gateway, Cloudflare, etc.), you may configure CORS there instead. In that case, keep Flask-CORS turned off or tightly scoped to avoid conflicting headers.
FAQ: examples of Flask-CORS and common questions
Q: Can you show a minimal example of Flask-CORS that only allows GET requests?
Yes. Here’s a very focused example of Flask-CORS: handling cross-origin requests with only GET allowed:
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(
app,
resources={r"/api/*": {"origins": "https://app.example.com"}},
methods=["GET"],
)
@app.route("/api/read-only")
def read_only():
return jsonify({"mode": "read-only"})
Q: Do I always need Flask-CORS for mobile apps?
Not always. Native mobile HTTP clients (like URLSession on iOS or OkHttp on Android) don’t enforce browser CORS rules. But if your mobile app embeds a browser or WebView, the same examples of Flask-CORS: handling cross-origin requests still apply.
Q: How do I test that my CORS configuration is correct?
Use your browser’s DevTools Network tab and look at the response headers. You should see Access-Control-Allow-Origin, Access-Control-Allow-Methods, and, when relevant, Access-Control-Allow-Credentials. You can also write small fetch tests in the browser console to simulate real calls.
Q: Are there security risks in using very open CORS configs?
Yes. When you use * for origins and allow credentials, or when you expose sensitive headers, you broaden the attack surface for CSRF-like attacks and data exfiltration. The safer pattern is what you see in the best examples of Flask-CORS: handling cross-origin requests—explicit origins, explicit methods, and explicit headers.
Q: Where can I learn more about HTTP, CORS, and browser behavior?
The MDN Web Docs CORS page is a solid reference, and OWASP’s guidance on web security gives you broader context around cross-origin risks and mitigations.
The bottom line: the strongest examples of Flask-CORS: handling cross-origin requests don’t just “make the error go away.” They encode your trust decisions in code—who can call what, with which methods, from which origins. Once you treat CORS as part of your security design instead of an afterthought, Flask-CORS becomes a very predictable, very boring piece of your stack—which is exactly what you want from security plumbing.
Related Topics
Examples of User Authentication in Flask: 3 Practical Patterns You’ll Actually Use
Best real-world examples of Flask-Migrate database migration examples
Practical examples of Flask-CORS: Handling Cross-Origin Requests
Flask Forms Made Human: How Data Really Moves From Browser to Python
Practical examples of creating RESTful APIs with Flask in 2025
Best examples of 3 practical examples of creating a basic Flask application
Explore More Flask Code Snippets
Discover more examples and insights in this category.
View All Flask Code Snippets