One question almost every frontend developer asks at some point:
"My frontend is running on localhost:3000 and my backend is running on localhost:5000. Both are on my own machine. Why am I still getting a CORS error?"
It feels strange because both applications are literally running on the same laptop.
The answer lies in how browsers define an Origin.
What Is an Origin?
An origin is made up of:
Protocol + Domain + Port
For example:
http://localhost:3000
and
http://localhost:5000
have:
- Same protocol ✅
- Same domain ✅
- Different ports ❌
Because the ports are different, the browser treats them as two different origins.
What Happens During a Request?
Imagine your React app is running on:
http://localhost:3000
and it calls:
fetch("http://localhost:5000/users");
From the browser's perspective:
Origin A → localhost:3000
Origin B → localhost:5000
This is considered a cross-origin request.
Why Does the Browser Care?
Imagine if websites could freely call APIs from any origin.
A malicious website could:
- Read your banking data
- Access your private APIs
- Perform actions on your behalf
To prevent this, browsers enforce the Same-Origin Policy.
By default:
Website A cannot access Website B's resources
unless Website B explicitly allows it.
How Does CORS Solve This?
CORS stands for:
Cross-Origin Resource Sharing
It is simply a mechanism that lets the server tell the browser:
"Yes, I trust requests coming from this origin."
Example response header:
Access-Control-Allow-Origin: http://localhost:3000
Now the browser allows the frontend to access the response.
Important Thing To Understand
The backend usually receives the request successfully.
The CORS error is often raised by the browser after receiving the response.
The flow looks like:
Frontend
↓
Backend Receives Request ✅
↓
Backend Sends Response ✅
↓
Browser Blocks Response ❌
That's why you sometimes see the API hit in your backend logs but still get a CORS error in the browser.
Why Doesn't Postman Show CORS Errors?
Because CORS is a browser security feature.
Tools like:
- Postman
- cURL
- Insomnia
don't enforce browser security policies.
So the same request works perfectly there.
The Key Takeaway
Even though both applications are running on the same machine:
localhost:3000
localhost:5000
they are considered different origins because the ports are different.
The browser doesn't care that they're on the same laptop. It only cares about the origin.
That's why CORS exists, and that's why adding the correct Access-Control-Allow-Origin header fixes the issue.
Top comments (0)