If you’ve ever seen an error like “Access to fetch at '...' from origin '...' has been blocked by CORS policy”, you’ve probably run into a Cross-Origin Resource Sharing (CORS) issue.
But what is CORS, why does it exist, and how can you fix it?
Let’s break it down.
🌍 What is a cross-origin request?
A cross-origin request happens when a web page makes a request to a different domain (or subdomain, or port) than the one that served the page.
Example:
Frontend URL: https://my-app.com
API URL: https://api.my-app.com
Even though both URLs look similar, they’re considered different origins by the browser.
🚧 Why does CORS exist?
CORS is a security feature implemented by web browsers to prevent malicious websites from reading sensitive data from another domain without permission.
Without CORS, any website could make requests to your bank’s API using your browser’s credentials—not ideal.
📜 How CORS works
When the browser detects a cross-origin request, it adds an Origin header and waits to see if the server allows that origin.
Example request headers:
Origin: https://my-app.com
The server must explicitly respond with a matching header:
Access-Control-Allow-Origin: https://my-app.com
If it doesn’t? The browser blocks the response.
🧪 Simple CORS flow
Let’s say your frontend at https://my-app.com
calls an API at https://api.my-app.com
.
1. The browser sends a request with an origin
header
2. The server responds with access-control-allow-origin
3. If the origin is allowed, the browser continues
If not allowed? You get the classic:
> ❌ CORS Error: Blocked by CORS policy
⚠️ What is a preflight request?
For some types of requests (like POST
with JSON or custom headers), the browser first sends a preflight request using OPTIONS
.
OPTIONS /users HTTP/1.1
Origin: https://my-app.com
Access-Control-Request-Method: POST
The server must respond with:
Access-Control-Allow-Origin: https://my-app.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type
Only then will the browser send the actual request.
🔧 How to fix CORS (Server-Side)
You need to configure the server to allow requests from the desired origins.
Example in Node.js with Express:
import cors from 'cors';
import express from 'express';
const app = express();
app.use(cors({
origin: 'https://my-app.com',
methods: ['GET', 'POST', 'PUT'],
credentials: true
}));
This allows only requests from your frontend to reach the backend.
🧩 Common CORS config mistakes
- ❌ Allowing but also trying to send cookies (
credentials: true
) - ❌ Missing
Access-Control-Allow-Headers
for custom headers - ❌ Not handling
OPTIONS
method correctly for preflight - ❌ Allowing too many origins without validation (security risk)
✅ CORS Checklist
- ✅ Understand what counts as “cross-origin”
- ✅ Know when preflight requests are triggered
- ✅ Configure your backend with the correct CORS headers
- ✅ Don’t forget credentials and headers when needed
🧠 Conclusion
CORS may seem like a frustrating blocker, but it’s actually protecting users from dangerous cross-origin attacks.
By understanding how it works-and configuring your server correctly-you can avoid the errors and build safer APIs.
Tools like Postman, browser devtools, and proxy servers can help test and debug CORS issues in development.