DEV Community

Cover image for That CORS Error Isn’t a Bug — It’s Actually Protecting Your Web App
Yukti Sahu
Yukti Sahu

Posted on

That CORS Error Isn’t a Bug — It’s Actually Protecting Your Web App

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
Enter fullscreen mode Exit fullscreen mode

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.

diagram of the cors flow and explanations
Suppose you are logged into:

  • 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")
Enter fullscreen mode Exit fullscreen mode

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:

  • Schemehttp or https
  • Host → domain name
  • Port80, 443, 5173, etc.

If any one of these changes, the origin is different.

Examples:

  • https://yuktisahu.devhttps://api.yuktisahu.dev (different host)
  • https://yuktisahu.devhttp://yuktisahu.dev (different scheme)
  • http://localhost:5173http://localhost:8000 (different port)
  • /page1 and /page2 on 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:

  1. Your frontend sends a request to another origin
  2. The browser automatically adds an Origin header
  3. The server checks this Origin
  4. The server decides whether it trusts that origin
  5. If trusted, the server sends this header in response: Access-Control-Allow-Origin: https://yuktisahu.dev
  6. 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"
})
Enter fullscreen mode Exit fullscreen mode

When you do this, the rules become stricter.

Now the server cannot respond with:

Access-Control-Allow-Origin: *
Enter fullscreen mode Exit fullscreen mode

Instead, it must explicitly say which origin is allowed:

Access-Control-Allow-Origin: https://yuktisahu.dev
Access-Control-Allow-Credentials: true
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)