How to Fix CORS Error - Missing Access-Control-Allow-Origin Header
Quick Answer: CORS (Cross-Origin Resource Sharing) errors occur when a browser blocks requests from one domain to another due to missing or incorrect CORS headers. The server must include 'Access-Control-Allow-Origin' header to allow cross-origin requests. Add CORS headers to your backend API or use a CORS proxy to fix this.
What Causes This Error
- Backend API missing 'Access-Control-Allow-Origin' header in response
- Frontend making request from different domain (http vs https, different port)
- Server configured to only allow specific origins, not your frontend domain
- Preflight OPTIONS request rejected by server
- Browser security policy preventing cross-origin requests without CORS headers
- API using outdated or incorrect CORS header format
- Credentials (cookies, auth) included in request without proper CORS configuration
- Request includes custom headers not allowed by CORS policy
Step-by-Step Fixes
Fix 1: Add CORS Headers to Backend API (Node.js/Express)
Install CORS middleware: 'npm install cors',Add to your Express app: 'const cors = require("cors"); app.use(cors());',For specific origin, use: 'app.use(cors({ origin: "https://yourdomain.com" }));',For multiple origins: 'app.use(cors({ origin: ["https://domain1.com", "https://domain2.com"] }));',Allow credentials: 'app.use(cors({ origin: "https://yourdomain.com", credentials: true }));',Restart your server and test the request
Fix 2: Add CORS Headers Manually (Python/Flask)
Install Flask-CORS: 'pip install flask-cors',Add to your Flask app: 'from flask_cors import CORS; CORS(app)',For specific origin: 'CORS(app, origins=["https://yourdomain.com"])',For specific routes: '@app.route("/api/data") @cross_origin() def get_data(): ...',Allow credentials: 'CORS(app, supports_credentials=True)',Restart Flask server and test
Fix 3: Configure CORS in Nginx Reverse Proxy
Edit Nginx config: 'sudo nano /etc/nginx/sites-enabled/default',Add CORS headers in server block:,add_header 'Access-Control-Allow-Origin' '*' always;,add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;,add_header 'Access-Control-Allow-Headers' 'Content-Type' always;,For preflight OPTIONS requests, add: 'if ($request_method = OPTIONS) { return 204; }',Test Nginx config: 'sudo nginx -t' and reload: 'sudo systemctl reload nginx'
Fix 4: Fix Preflight OPTIONS Request Handling
Browser sends OPTIONS preflight request before actual request,Ensure backend responds to OPTIONS with 200 status and CORS headers,In Express: 'app.options("*", cors());' to handle all preflight requests,In Flask: Add OPTIONS method to route: '@app.route("/api/data", methods=["GET", "OPTIONS"])',Verify preflight response includes: 'Access-Control-Allow-Methods', 'Access-Control-Allow-Headers',Test with curl: 'curl -X OPTIONS -H "Origin: https://yourdomain.com" https://api.example.com/data'
Fix 5: Use CORS Proxy for Third-Party APIs
If calling third-party API without CORS support, use CORS proxy,Popular proxy: 'https://cors-anywhere.herokuapp.com/' or 'https://api.allorigins.win/',Modify request URL: 'https://cors-anywhere.herokuapp.com/https://api.example.com/data',Note: CORS proxies are temporary solutions; contact API provider for proper CORS support,For production, host your own CORS proxy server,Better approach: Use backend-to-backend API calls instead of frontend-to-third-party
FAQs
Q: What's the difference between CORS and Same-Origin Policy?
A: Same-Origin Policy is a browser security feature that blocks cross-origin requests by default. CORS is a mechanism to allow specific cross-origin requests. CORS headers tell the browser which cross-origin requests are safe.
Q: Can I use Access-Control-Allow-Origin: * in production?
A: Using '*' allows any domain to access your API, which is a security risk. In production, specify exact allowed origins: 'Access-Control-Allow-Origin: https://yourdomain.com'. This prevents unauthorized access.
Q: Why does my request work in Postman but fail in the browser?
A: Postman doesn't enforce CORS because it's not a browser. Browsers enforce CORS for security. Your API needs proper CORS headers for browser requests.
Q: How do I allow credentials (cookies) in CORS requests?
A: Set 'Access-Control-Allow-Credentials: true' on server and 'credentials: "include"' in fetch/axios on client. Note: You cannot use '*' for origin when credentials are included.
Q: What custom headers need CORS allowance?
A: Standard headers (Content-Type, Accept) are usually allowed. Custom headers (Authorization, X-API-Key) need explicit allowance via 'Access-Control-Allow-Headers' header.