Why Your Browser Blocks Some Requests: CORS Explained Simply

You've built your frontend. You've built your backend. You connect them. Everything should work perfectly.
Then you open the browser console and see:
"Access to fetch at 'your-api.com' has been blocked by CORS policy"
What the hell is CORS? Why is it blocking you? And why does every developer curse at it at least once in their career?
Let's demystify the annoying security guard that's actually trying to protect you.
What Is CORS?
CORS stands for Cross-Origin Resource Sharing. Translation: "Rules for when your website can talk to other websites."
Your browser is paranoid. When your website (running on yoursite.com) tries to fetch data from another server (like api.example.com), the browser goes: "Hold up. Should I allow this? What if this is a trap?"
That's CORS. It's the browser's bouncer checking if the request should be allowed.
The Security Guard Analogy
Imagine your website is an apartment building. Your frontend code lives in Apartment A (yoursite.com). Your backend API lives across town in Building B (api.example.com).
Without CORS: Anyone from any apartment can walk into Building B, grab data, and leave. Sounds convenient, but also sounds like a security nightmare. A malicious website (evil.com) could trick your browser into fetching your bank account data from bank.com and send it to the attacker.
With CORS: Building B has a security guard (the browser) at the entrance. When you (Apartment A) try to walk in, the guard checks:
"Are you allowed here?"
"Do you have the right credentials?"
"Did Building B say you can come in?"
If Building B (your backend) says "yeah, Apartment A is cool," the guard lets you through. If not? "Access denied. CORS error."
What's "Same Origin"?
Here's the basic rule: Browsers allow requests to the same origin automatically. No questions asked.
Same origin means:
Same protocol (http vs https)
Same domain (yoursite.com)
Same port (3000, 8080, etc.)
Examples:
Your page is at https://yoursite.com:
Request to
https://yoursite.com/api/users→ ✅ Same origin, allowedRequest to
http://yoursite.com/api/users→ ❌ Different protocol (http vs https)Request to
https://api.yoursite.com/users→ ❌ Different subdomainRequest to
https://yoursite.com:8080/users→ ❌ Different port
Even a tiny difference = different origin = CORS check required.
Why Browsers Are So Paranoid
Imagine this attack scenario:
You're logged into your bank at
bank.comYou visit
evil.com(malicious site)evil.comsecretly makes a request tobank.com/transfer-moneySince you're logged in, your browser sends your auth cookies automatically
Money gets transferred to the attacker
Without CORS: This works. Game over.
With CORS: The browser blocks step 3. bank.com didn't give evil.com permission to make requests, so the browser says "nope" and throws a CORS error.
CORS protects you from this. That annoying error? It's literally saving you from getting hacked.
When CORS Errors Happen
Common scenario: You're developing locally.
Frontend runs on
http://localhost:3000Backend runs on
http://localhost:8000
Different ports = different origins = CORS check = error.
Another scenario: Frontend on yoursite.com, API on api.yoursite.com. Different subdomains = CORS error.
The twist: CORS only affects browsers. If you use Postman, curl, or any non-browser tool to test your API? No CORS errors. Why? Because CORS is a browser security feature, not a server one.

How Developers Fix CORS
Option 1: Tell your backend to allow specific origins
Your backend needs to say "yes, localhost:3000 is allowed to talk to me."
In most backend frameworks, you add headers like:
Access-Control-Allow-Origin: <http://localhost:3000>
Translation: "I, the backend, give permission for localhost:3000 to access me."
Option 2: Use a wildcard (dangerous in production)
Access-Control-Allow-Origin: *
Translation: "Anyone from anywhere can access me."
Great for development. Terrible for production. Don't do this unless your API is truly public.
Option 3: Use a proxy during development
Run a proxy that forwards requests from your frontend to your backend. Since both use the same origin, no CORS issues. Tools like Vite and Create React App have built-in proxy support.
Option 4: Deploy frontend and backend to the same domain
If both are on yoursite.com, same origin = no CORS. Some developers put the frontend at yoursite.com and API at yoursite.com/api.
Why CORS Seems So Annoying
CORS feels like it's in your way because you're usually hitting it during development:
Frontend and backend on different ports
Testing API calls from localhost
Trying things quickly without configuring anything
In production, you typically:
Deploy frontend and backend properly
Configure CORS headers once
Never think about it again
CORS errors during development are a rite of passage. Every developer has spent 2 hours debugging "why won't this work?!" only to realize they forgot to add CORS headers.
The Bottom Line
CORS is your browser being a paranoid bodyguard. Annoying when it blocks you, essential for security.
When you see "blocked by CORS policy":
Check your backend CORS config
Add your frontend's origin to the allowed list
Move on with your life
It's a solved problem. You just need to tell your backend "yes, this origin is allowed."
Fix your backend headers, refresh the page, and watch the magic happen.
Welcome to web development, where security features feel like obstacles until they save you from disaster.



