Solving "CORS error" and common Access-Control-Allow-Origin issues: A Complete Guide
If you've ever built a web application that makes requests to an API on a different domain, you've almost certainly encountered the dreaded "CORS error." It usually looks something like this in your browser console:
Access to fetch at 'https://api.example.com' from origin 'https://myapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
In this guide, we will explain exactly what CORS is, why it exists, and how to fix these errors for good.
1. Common CORS Error Messages
You will primarily see these errors in your browser's Developer Tools (Console or Network tab):
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present ...The 'Access-Control-Allow-Origin' header contains multiple values ...Response to preflight request doesn't pass access control check ...Method NOT ALLOWED ...(when the HTTP method like POST or DELETE isn't permitted by CORS)
2. What is CORS?
CORS (Cross-Origin Resource Sharing) is a security feature implemented by browsers. It prevents a malicious website from making requests to a different domain (like your bank or your private API) without permission.
By default, browsers follow the Same-Origin Policy, meaning a script on a.com can only request data from a.com. CORS is the mechanism that allows a.com to safely request data from b.com if b.com explicitly allows it.
3. Top Causes and Solutions
3.1 Missing "Access-Control-Allow-Origin" Header
This is the most common error. It means the server you are requesting data from hasn't told the browser that your domain is allowed to access the resource.
The Solution:
The fix MUST happen on the Server-side. You need to add the Access-Control-Allow-Origin header to the response.
- For public APIs: Set it to
*(allow all). - For private APIs: Set it to your specific domain (e.g.,
https://myapp.com).
3.2 CORS Preflight Failures
For "complex" requests (like those with custom headers or methods like PUT/DELETE), the browser sends an automatic OPTIONS request first. This is called a Preflight request.
The Error:
Response to preflight request doesn't pass access control check.
The Solution:
Ensure your server handles OPTIONS requests and returns a 200 OK or 204 No Content status with the correct CORS headers:
Access-Control-Allow-OriginAccess-Control-Allow-Methods(e.g.,GET, POST, OPTIONS, PUT, DELETE)Access-Control-Allow-Headers(e.g.,Content-Type, Authorization)
3.3 "Access-Control-Allow-Credentials"
If you are sending cookies or authorization headers with your request (withCredentials: true), CORS rules become stricter.
The Error:
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
The Solution:
- You cannot use
*forAccess-Control-Allow-Origin. You must specify the exact origin. - You must also add the header:
Access-Control-Allow-Credentials: true.
4. How to Fix CORS in Different Environments
4.1 Node.js (Express)
The easiest way is to use the cors middleware:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://myapp.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true
}));
4.2 Nginx
Add these lines to your server or location block:
add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
if ($request_method = 'OPTIONS') {
return 204;
}
4.3 Python (Flask)
Use the flask-cors extension:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app, origins=["https://myapp.com"])
5. FAQ: Frequently Asked Questions
Q: Can I fix a CORS error from the frontend (JavaScript)?
A: No. CORS is a server-side security policy enforced by the browser. You cannot "bypass" it in your JavaScript code. If you don't control the server, you must use a Proxy Server to fetch the data for you.
Q: Why do I only see CORS errors in the browser and not in Postman?
A: Postman is a standalone application, not a web browser. It does not enforce the Same-Origin Policy or CORS rules. Only web browsers (Chrome, Firefox, etc.) enforce CORS.
Q: What is the risk of setting Access-Control-Allow-Origin to "*"?
A: For public data, there is no risk. However, for an API that handles user data or requires authentication, setting it to * allows any website to make requests on behalf of a logged-in user, potentially leading to data theft.
6. Summary Table of CORS Headers
| Header | Description |
|---|---|
Access-Control-Allow-Origin |
Specifies which domains are allowed to access the resource. |
Access-Control-Allow-Methods |
Specifies which HTTP methods (GET, POST, etc.) are permitted. |
Access-Control-Allow-Headers |
Specifies which custom headers can be sent. |
Access-Control-Allow-Credentials |
Indicates whether the response can be shared when the credentials flag is true. |
Access-Control-Max-Age |
Specifies how long the results of a preflight request can be cached. |