Skip to main content

Command Palette

Search for a command to run...

Why Your Browser Blocks Some Requests: CORS Explained Simply

Published
4 min read
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, allowed

  • Request to http://yoursite.com/api/users → ❌ Different protocol (http vs https)

  • Request to https://api.yoursite.com/users → ❌ Different subdomain

  • Request 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:

  1. You're logged into your bank at bank.com

  2. You visit evil.com (malicious site)

  3. evil.com secretly makes a request to bank.com/transfer-money

  4. Since you're logged in, your browser sends your auth cookies automatically

  5. 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:3000

  • Backend 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":

  1. Check your backend CORS config

  2. Add your frontend's origin to the allowed list

  3. 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.