If you've worked with APIs in a web app, you've probably seen this error at least once:
Access to fetch has been blocked by CORS policy
And honestly, it feels annoying.
Your API URL is correct.
Your code looks fine.
But the browser just refuses to cooperate.
At first, it feels like a bug or misconfiguration. But the truth is:
CORS is not an error — it's a security feature doing exactly what it's supposed to do.
In this article, let's understand CORS in simple words and see why it exists, what problems it solves, and why the browser behaves this way.
1. Why CORS Exists in the First Place
To understand CORS, we need to imagine a situation without it.
facebook.com- or your bank website like
hdfc.com
Your browser stores cookies or tokens so you stay logged in.
Now, in another tab, you open a random website — maybe a malicious one. That website also runs JavaScript.
If there were no restrictions, that JavaScript could send requests like:
fetch("https://hdfc.com/api/balance")
Because the request is coming from your browser, your bank cookies would automatically be sent along.
The bank server would think:
"This request is from a logged-in user."
And it might return sensitive data like your balance.
This is dangerous.
To prevent this, browsers enforce something called the Same-Origin Policy (SOP):
- A website can only access data from the same origin by default.
CORS (Cross-Origin Resource Sharing) is a controlled way to relax this rule — but only when the server explicitly allows it.
2. What Exactly is an "Origin"?
An origin is made of three things:
-
Scheme →
httporhttps - Host → domain name
-
Port →
80,443,5173, etc.
If any one of these changes, the origin is different.
Examples:
-
https://yuktisahu.dev❌https://api.yuktisahu.dev(different host) -
https://yuktisahu.dev❌http://yuktisahu.dev(different scheme) -
http://localhost:5173❌http://localhost:8000(different port) -
/page1and/page2on the same domain ✅ (same origin — path doesn't matter)
This is important because browsers use this definition to decide whether a request is cross-origin or not.
3. Why You Can't Fix CORS from the Frontend
This is one of the most confusing parts for beginners.
You see the error in the browser console, so you try to fix it in your frontend code.
But CORS is not controlled by frontend code.
Here's what actually happens:
- Your frontend sends a request to another origin
- The browser automatically adds an
Originheader - The server checks this
Origin - The server decides whether it trusts that origin
- If trusted, the server sends this header in response:
Access-Control-Allow-Origin: https://yuktisahu.dev - If this header is missing or doesn't match your origin: The browser blocks the response Your JavaScript code never gets access to it
So even if the server does respond, the browser refuses to give that response to your code.
That's why CORS must be fixed on the server, not the frontend.
4. Why It Works in Postman but Not in the Browser
Another very common confusion:
"The API works in Postman, so why does it fail in my web app?"
Because CORS is a browser security rule, not a server rule.
Postman:
- Is not a browser
- Has no cookies from other websites
- Has no logged-in user sessions to protect
Browsers, on the other hand:
- Run code from many websites at once
- Store cookies for sensitive sites
- Must protect users from data leaks
So only browsers enforce CORS. Postman and curl don't need to.
5. Cookies Make CORS Stricter
Sometimes your frontend needs to send cookies along with the request.
In fetch, this looks like:
fetch(url, {
credentials: "include"
})
When you do this, the rules become stricter.
Now the server cannot respond with:
Access-Control-Allow-Origin: *
Instead, it must explicitly say which origin is allowed:
Access-Control-Allow-Origin: https://yuktisahu.dev
Access-Control-Allow-Credentials: true
This is intentional.
If cookies are involved, the server must clearly trust one specific origin, not everyone.
6. What is a Preflight Request?
Some requests are simple, like:
GET- basic
POST
Others are considered complex, such as:
-
PUT,PATCH,DELETE - requests with custom headers
- JSON content types
For these, the browser sends an extra request first:
OPTIONS /api
This is called a preflight request.
It's the browser asking:
"Is it okay if I send this kind of request with these headers?"
If the server responds with the right CORS headers, the browser sends the actual request.
If not, the browser blocks it completely.
Final Thoughts
CORS feels frustrating because it stops your code.
But it exists to protect:
- logged-in users
- sensitive data
- browser security boundaries
Once you understand that:
- CORS errors make more sense
- debugging becomes easier
- you know the fix is always on the server side
So the next time you see a CORS error, instead of thinking "something is broken", think:
"The browser is protecting users — and the server hasn't given permission yet."
That small mindset shift really helps.

Top comments (0)