In the world of modern web development, your frontend often needs to talk to an API. But when your frontend lives on domain-a.com
and your backend API lives on domain-b.com
, browsers don’t just allow this by default — that’s where CORS comes in.
If you’ve ever seen a CORS error in the console and scratched your head, this post is for you.
🧙♂️ What is CORS?
CORS (Cross-Origin Resource Sharing) is a browser security feature that controls whether and how frontend apps running on one origin can access resources from a different origin.
In simpler terms:
It’s a way for servers to say: “Hey browser, it’s okay if this site wants to talk to me.”
🌐 Same-Origin Policy — The Root of CORS
Before we dive deeper into CORS, let’s talk about the Same-Origin Policy (SOP) — the foundation of browser security.
Under SOP, a web page can only request resources from the same origin — that means:
-
Same protocol (e.g.,
https
) -
Same domain (e.g.,
example.com
) -
Same port (e.g.,
:443
)
Cross-origin examples that will be blocked:
-
http://example.com
(wrong protocol) -
https://example.com:3000
(wrong port) -
https://api.example.com
(different subdomain)
🔀 What is a Cross-Origin Request?
Any request from one origin to a different origin is a cross-origin request.
For example, if your frontend lives at:
https://frontend-app.com
And you want to call:
https://api.backend-service.com
That’s a cross-origin request — and by default, the browser will block it unless the server explicitly allows it.
🔐 Why Does CORS Exist?
CORS exists to protect users. Without it, malicious sites could:
-
Steal data from other websites you’re logged into
-
Impersonate you when sending requests to other services
So, CORS makes sure that only trusted sites can access resources on your server.
⚖️ How CORS Works
When a browser makes a cross-origin request, it adds an Origin
header to tell the server where the request is coming from:
Origin: https://frontend-app.com
The server then decides whether to allow it by responding with:
Access-Control-Allow-Origin: https://frontend-app.com
If the origin is allowed — great. If not, the browser blocks the response.
🔄 Types of CORS Requests
1. Simple Requests
These are requests using:
-
Methods:
GET
,POST
, orHEAD
-
Standard headers only
No extra work needed unless you’re blocking them explicitly.
2. Preflight Requests
If a request:
-
Uses methods like
PUT
,DELETE
-
Sends custom headers (like
Authorization
)
Then the browser sends a preflight OPTIONS request to check if it’s allowed.
Preflight example:
Browser sends:
OPTIONS /api/data
Origin: https://frontend.com
Access-Control-Request-Method: PUT
Server responds:
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: PUT, GET
Access-Control-Allow-Headers: Content-Type
If approved, the actual request is made.
🧠 Key CORS Headers
Header | Description |
---|---|
Access-Control-Allow-Origin |
Which origin(s) are allowed |
Access-Control-Allow-Methods |
HTTP methods you permit (GET, POST, etc.) |
Access-Control-Allow-Headers |
Custom headers that are allowed |
Access-Control-Allow-Credentials |
Allow cookies or auth credentials |
Access-Control-Expose-Headers |
Headers the browser can read from the response |
Access-Control-Max-Age |
Time to cache the preflight response |
⚙️ Enabling CORS on the Server
Node.js (Express)
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors()); // Allow all origins
// Or for a specific origin:
app.use(cors({
origin: 'https://your-frontend.com',
methods: ['GET', 'POST'],
credentials: true
}));
Python (Flask)
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # Allow all origins
# Or specify origin
CORS(app, origins=["https://your-frontend.com"])
⚡ Common CORS Errors
-
No ‘Access-Control-Allow-Origin’ header: The server didn’t allow this origin
-
Preflight request failed: Server didn’t respond correctly to the OPTIONS request
-
Credentials not allowed: Missing
Access-Control-Allow-Credentials: true
🚀 Summary
Concept | Description |
---|---|
What is CORS? | A mechanism to allow or block cross-origin requests |
Why it matters? | To protect users from unauthorized access |
Controlled by | The server via HTTP headers |
Implemented in | Browsers for security enforcement |
✨ Final Thoughts
CORS can feel confusing at first, but once you understand how the browser and server communicate via headers, it all makes sense.
If you’re a frontend developer and hit a CORS error, it means you need to work with your backend team (or configure your server) to allow your app’s origin. And always remember: CORS is there to protect your users.
Have questions or stuck with a specific CORS issue? Drop it in the comments!