CORS (Cross-Origin Resource Sharing) is a security feature implemented by web browsers to restrict how resources on a web page can be requested from another domain.
For example, if your frontend (React, Angular, Vue, etc.) is running on http://localhost:3000
and your backend (Flask, Django, Node.js, etc.) is on http://localhost:5000
, CORS prevents the frontend from making API requests unless explicitly allowed.
🔍 Common CORS Issues and Fixes
1️⃣ CORS Policy Blocked (No ‘Access-Control-Allow-Origin’ Header)
Error Message:
Access to fetch at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Fix: Add CORS Headers in the Backend
- Flask (Python)
from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app) # Allow all domains
Or allow specific domains: pythonCopyEditCORS(app, origins=["http://localhost:3000"])
- Django Install
django-cors-headers
: shCopyEditpip install django-cors-headers
Add tosettings.py
:INSTALLED_APPS = [ ... 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ... ] CORS_ALLOW_ALL_ORIGINS = True # Allow all origins # OR allow specific origins: CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "https://yourfrontend.com", ]
- Express (Node.js)
const cors = require('cors'); app.use(cors()); // Allow all origins
2️⃣ Preflight Request Blocked (OPTIONS Request Fails)
Error Message:
Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked due to CORS policy.
This happens when browsers send an OPTIONS request before making the actual request.
Fix: Allow OPTIONS Requests in Backend
- Flask
from flask_cors import CORS CORS(app, supports_credentials=True)
- Django
CORS_ALLOW_METHODS = [ "GET", "POST", "OPTIONS", "PUT", "DELETE", ]
- Express (Node.js)
app.use(cors({ origin: "http://localhost:3000", methods: ["GET", "POST", "OPTIONS", "PUT", "DELETE"], credentials: true }));
3️⃣ CORS Error Due to Credentials (Cookies, Auth Headers Blocked)
Error Message:
Credentials flag is true, but 'Access-Control-Allow-Origin' is '*'
By default, credentials (cookies, tokens) are not shared across origins.
Fix: Allow Credentials
- Flask
CORS(app, supports_credentials=True)
- Django
CORS_ALLOW_CREDENTIALS = True
- Express (Node.js)
app.use(cors({ origin: "http://localhost:3000", credentials: true }));
- Frontend (JavaScript)
fetch("http://api.example.com/data", { method: "GET", credentials: "include" });
4️⃣ CORS Error Only in Production (Works in Development)
If CORS works locally but breaks in production, the production server might be blocking cross-origin requests.
Fix:
- Ensure CORS headers are sent in production.
- Check the server logs for errors.
- If using NGINX, add CORS headers:
add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
🚀 Debugging Tips
- Use DevTools: Open the browser’s Developer Console (F12 > Network > Headers) and check if the
Access-Control-Allow-Origin
header is present. - Check API Response: Test with
curl
:curl -I http://api.example.com
- Temporarily Disable CORS for Testing:
Use the Chrome extension “CORS Unblock”, but only for debugging.