
Why Your API Works in Postman but Fails in the Browser
Suman Kumar Keshari
Founder of Skilldham and Software Engineer
If you’ve been building web apps long enough, you’ve probably had this moment.
You test your API in Postman.
Everything works perfectly.
200 OKResponse looks good. JSON looks good. Headers look good.
So you move to the frontend and connect the API.
And suddenly the browser throws this:
Access to fetch at 'https://api.example.com' from origin 'http://localhost:3000'
has been blocked by CORS policy.At this point most developers think one of three things:
The API is broken
The frontend code is wrong
The server is down
But none of those are the real problem.
The real problem is something Postman never tells you about.
The browser is enforcing security rules that Postman completely ignores.
Postman Is Not a Browser
This is the first thing that confuses developers.
Postman is just an HTTP client. It sends requests and receives responses.
It doesn’t care where the request came from.
Browsers do.
Browsers enforce something called the Same-Origin Policy, which exists to protect users from malicious websites stealing data from other services.
Because of this rule, a website running at:
http://localhost:3000cannot freely request data from:
https://api.example.comunless the server explicitly allows it.
Postman doesn’t enforce this rule. Browsers do.
So your API may be perfectly fine — it’s just missing the permissions browsers require.
What CORS Actually Is
CORS stands for Cross-Origin Resource Sharing.
It’s basically a system where the server tells the browser:
“It’s okay for this website to access my API.”
This permission is given through response headers.
For example:
Access-Control-Allow-Origin: http://localhost:3000If the server doesn’t send this header, the browser blocks the request.
Not because the API failed.
But because the browser refuses to expose the response.
Why It Feels Like the API Is Broken
The frustrating part is that the API did work.
The request actually reaches the server.
The server may even respond successfully.
But the browser hides the response from JavaScript.
So from the frontend perspective it looks like:
Network Erroror
CORS blockedThis is why debugging this issue is confusing for beginners.
The backend logs show success. The frontend shows failure.
Both are technically correct.
The Hidden Request Developers Don’t See
When the browser detects a cross-origin request, it sometimes sends a preflight request before the real request.
This request looks like this:
OPTIONS /api/dataIt asks the server:
Are cross-origin requests allowed?
Which methods are allowed?
Which headers are allowed?
If the server doesn't respond correctly, the browser never sends the real request.
This is another reason Postman behaves differently.
Postman skips this entire process.
The Most Common CORS Fix
Most of the time the solution is simply adding proper headers on the backend.
For example in Node.js Express:
import cors from "cors";
app.use(cors({
origin: "http://localhost:3000",
credentials: true
}));Or manually:
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE");
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
next();
});Once the server sends these headers, the browser allows the request.
A Common Mistake Developers Make
Many developers try to fix CORS on the frontend.
They add headers like this:
fetch(url, {
headers: {
"Access-Control-Allow-Origin": "*"
}
});This does nothing.
CORS headers must come from the server, not the client.
The browser ignores any CORS headers sent by frontend code.
Cookies Make CORS More Complicated
Another issue appears when authentication is involved.
If your request includes cookies or sessions, the server must also allow credentials.
Example:
Access-Control-Allow-Credentials: trueAnd your frontend request must include:
fetch(url, {
credentials: "include"
});Without this, authentication requests silently fail.
Why It Works Locally but Breaks in Production
Many teams fix CORS for localhost but forget about production domains.
For example:
Access-Control-Allow-Origin: http://localhost:3000Then production frontend runs at:
https://app.example.comNow requests break again.
A safer configuration often looks like:
Access-Control-Allow-Origin: https://app.example.comOr dynamic origin handling.
Debugging CORS Like a Senior Developer
Instead of guessing, check these three things:
1. Look at Network Tab
Open browser DevTools → Network → Request headers.
Check:
Origin
Request method
Response headers
2. Check Preflight Response
Find the OPTIONS request.
Verify the server returns:
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers3. Check Server Logs
Confirm the request actually reached the server.
If it didn't, the problem may be:
reverse proxy
gateway
load balancer
CDN configuration
The Real Lesson
CORS errors aren’t actually backend bugs or frontend bugs.
They are security restrictions enforced by browsers.
Once you understand that:
debugging becomes easier
configuration becomes predictable
frustration disappears
Almost every developer hits this problem at least once.
The difference between a junior and a senior engineer is simply this:
Seniors recognize it immediately.
Skilldham Insight
If your API works in Postman but fails in the browser, the API probably isn't broken.
Your server just hasn't told the browser it's allowed to talk to it.
And the browser is doing exactly what it was designed to do.
Protect the user.
Frequently Asked Questions
1. Why does my API work in Postman but fail in the browser? Postman sends requests without enforcing browser security rules. Browsers apply the Same-Origin Policy and block requests unless the server allows them through proper CORS headers.
2. What is the most common cause of CORS errors? The server not sending the correct Access-Control-Allow-Origin header. Without this header, the browser blocks the response even if the API works correctly.
3. Can I fix CORS from the frontend code? No. CORS must be configured on the server. Any CORS headers added in frontend requests are ignored by the browser.
4. How do I quickly debug a CORS issue? Open the browser DevTools → Network tab → inspect the request and check if the response includes Access-Control-Allow-Origin and related headers.