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

Published: (December 27, 2025 at 12:37 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

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

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 mis‑configuration. 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, 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, 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 (maybe malicious) website. That site also runs JavaScript.

If there were no restrictions, that JavaScript could send a request like:

fetch("https://hdfc.com/api/balance")

Because the request originates 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 might return sensitive data like your balance.

This is dangerous.

To prevent this, browsers enforce 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 consists of three parts:

PartExample
Schemehttp or https
Hostdomain name (example.com)
Port80, 443, 5173, etc.

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

Examples

Origin AOrigin BSame?
https://yuktisahu.devhttps://api.yuktisahu.dev❌ (different host)
https://yuktisahu.devhttp://yuktisahu.dev❌ (different scheme)
http://localhost:5173http://localhost:8000❌ (different port)
https://example.com/page1https://example.com/page2✅ (same origin – path doesn’t matter)

Browsers use this definition to decide whether a request is cross‑origin.

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.

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. If the server trusts the origin, it includes the header in the response:

    Access-Control-Allow-Origin: https://yuktisahu.dev
  5. If the header is missing or doesn’t match your origin, the browser blocks the response, and your JavaScript never sees it.

So even if the server responds, 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 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.

ToolHow it treats CORS
Postman (or curl)Not a browser → no CORS enforcement, no cookies from other sites.
BrowsersRun code from many sites simultaneously, store cookies for sensitive sites, must protect users from data leaks.

Only browsers enforce CORS. Postman and curl don’t need to.

5. Cookies Make CORS Stricter

Sometimes your frontend needs to send cookies with the request:

fetch(url, {
  credentials: "include"
})

When you do this, the rules become stricter:

  • The server cannot respond with a wildcard:

    Access-Control-Allow-Origin: *
  • It must explicitly specify the allowed origin and also allow credentials:

    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”, e.g.:

  • GET
  • Basic POST (with Content-Type: application/x-www-form-urlencoded, multipart/form-data, or text/plain)

Other requests are considered “complex”, such as:

  • PUT, PATCH, DELETE
  • Requests with custom headers
  • Requests with Content-Type: application/json

For these, the browser sends an extra request first:

OPTIONS /api

This is called a preflight request. It asks the server:

“Is it okay if I send this kind of request with these headers?”

If the server responds with the appropriate CORS headers, the browser proceeds with 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 trying to “fix it in JavaScript”, check the server’s CORS configuration (or use a proxy during development) and you’ll be back on track.

Thinking “something is broken”, think:

“The browser is protecting users — and the server hasn’t given permission yet.”

Back to Blog

Related posts

Read more »

CORS - Cross Origin Resource Sharing

Introduction CORS Cross‑Origin Resource Sharing is one of those things you don’t really learn until you run into it. Everything may work on the server side—API...