CORS
Cross-Origin Resource Sharing — why it exists and how to configure it
Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.
UpgradeKnowledge Debt detected
You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.
Explanation
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that blocks web pages from making requests to a different domain than the one that served them.
The Same-Origin Policy:
A script on https://app.com cannot fetch https://api.example.com by default. They are different origins (different domain). This prevents malicious sites from silently making API calls using your logged-in cookies.
When CORS kicks in:
- Your React app on
localhost:3000calls your Flask API onlocalhost:5000→ CORS error app.comcallsapi.app.com→ CORS error (different subdomain)app.comcalls its ownapp.com/api→ no CORS (same origin)
How it works — the browser preflight:
Browser → OPTIONS /api/users HTTP/1.1 Origin: https://app.com Access-Control-Request-Method: POST Server → 200 OK Access-Control-Allow-Origin: https://app.com Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Authorization, Content-Type Browser → POST /api/users (actual request, now allowed)
Configuring CORS in Flask:
python from flask import Flask from flask_cors import CORS app = Flask(__name__) # Allow all origins (dev only — dangerous in production) CORS(app) # Restrict to specific origin (production) CORS(app, origins=["https://yourapp.com"]) # Or per-route @app.route("/api/data") @cross_origin(origins="https://yourapp.com") def data(): return {"ok": True}
Access-Control-Allow-Origin: * means anyone can call the API** — only use for truly public APIs.
Examples
CORS in FastAPI
FastAPI CORS configuration — list specific origins in production
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["https://yourapp.com", "http://localhost:3000"],
allow_credentials=True, # allows cookies/auth headers
allow_methods=["*"], # GET, POST, PUT, PATCH, DELETE, OPTIONS
allow_headers=["*"], # Authorization, Content-Type, etc.
)Why CORS errors happen in dev
CORS is a browser constraint — server-to-server requests are never blocked by CORS
# Common dev setup that causes CORS errors:
# - React dev server: http://localhost:3000
# - Flask API: http://localhost:5000
# These are DIFFERENT origins → browser blocks the request
# Fix option 1: Configure CORS on the server (shown above)
# Fix option 2: Proxy in Vite config (vite.config.ts)
# server: {
# proxy: {
# '/api': 'http://localhost:5000'
# }
# }
# Now requests go to localhost:3000/api → proxied to 5000
# Same origin from browser's perspective → no CORSHow well did you understand this?