What is CORS — and why that console error is protection, not a bug

You built a frontend, it calls your own API, and the console goes red: blocked by CORS policy. First thought: "the server is down." Here's the surprise: the server is alive, the request arrived, the response came back. The browser simply looked at that response and decided not to hand it to your code.
Sounds absurd — the server answered, but you can't see the answer? But that's the whole point of CORS. It's not a breakage. It's the browser protecting the user. Let's unpack what from — and why you fix it somewhere other than where the red is.
What CORS means in plain words
CORS stands for Cross-Origin Resource Sharing.
An "origin" is a bundle of three things: protocol + domain + port. https://myapp.com and https://api.myapp.com are different origins (the domain differs). http://localhost:3000 and http://localhost:8000 are different too (the port differs).
By default the browser has a strict rule: code from one origin cannot freely read responses from another. This is the Same-Origin Policy. CORS is the mechanism by which a server tells the browser: "this origin is allowed to read my responses, I permit it."
Analogy: two neighboring yards with a guard between them. By default he lets no strangers through. But the owner of the second yard can leave a list: "let in the residents from the house across the street." CORS is that allowlist.
Who CORS actually protects
Here's the big beginner confusion. CORS protects not your server. It protects the user in the browser.
Imagine: you're logged into your bank in one tab. In another you open an innocent-looking site. Without the Same-Origin Policy, a script on that site could quietly make a request to the bank in your name (your cookies are right there) and read the response — balance, transfers. The Same-Origin Policy forbids this: a foreign origin can't read the bank's response.
So CORS is a browser rule about reading responses, not a lock on the server. The server is still obliged to check who's knocking. So understand this: CORS doesn't make your API secure — it only stops foreign pages from reading responses behind the user's back.
Why you see the error
Now it's clear why the error is so strange. When your frontend on one origin calls an API on another, the browser lets the request through, the server processes it and replies. But before handing the reply to your JavaScript, the browser checks: does the response carry the permitting header Access-Control-Allow-Origin with your origin?
No header — the browser throws the response away and logs a CORS error. The request happened; you just didn't get the result.
Often, before the "real" request, the browser also sends a preflight — a short request with the OPTIONS method: "hey server, am I even allowed to reach you from this origin with this method?" If the server didn't reply to that OPTIONS with the right headers, the main request never even leaves.
How to fix it
Since a header in the response decides it, you fix it on the server, not in the frontend. Any browser tricks (disable it, bypass it) aren't a fix — they're self-deception.
- Find who sends the response — your backend, edge function, or proxy.
- Add the header
Access-Control-Allow-Originto the response with your origin, e.g.https://myapp.com. For local debugging,http://localhost:3000works. - Handle the preflight — the server must answer the
OPTIONSrequest with the same permitting headers, or the main request won't go through. - Don't use
*in production. A wildcard lets anyone read your responses. Fine for a public open API; for a private one, list specific origins.
In ready frameworks this is one or two lines or a plugin (cors in Express, a setting in Supabase Edge Functions). If your frontend and API live on the same origin — e.g. via a shared deploy with a proxy — the CORS problem doesn't arise at all. More on the process of calling another server is in the how to connect an API guide.
FAQ
Can I just disable CORS in the browser and stop suffering?
Only for your own local debugging (there are flags and extensions) — and it's a bad habit. Your users still have CORS on always, and you can't disable it for them. If it "only works with CORS off," the fix isn't done. Fix the headers on the server.
Does CORS protect my server from being hacked?
No. CORS is a browser rule about reading responses; it doesn't stop anyone from sending requests to your API directly (e.g. from a script outside the browser). API security is separate: authorization, token checks, rate limits. CORS just closes one specific scenario — stealing responses via a foreign tab.
Why does it work in Postman but fail in the browser?
Because CORS is a browser rule. Postman, curl, and server code aren't browsers — the Same-Origin Policy doesn't apply to them, so they get the response as-is. So "it's fine in Postman" doesn't mean CORS is configured; it means you tested around the very thing that enforces it.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





