CORS in JavaScript: Why Postman Works, But the Browser Doesn't?

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: When the Browser Says "No", But Postman Says "Yes"



Imagine this situation: you're writing frontend in JavaScript, making a fetch request to an API. In response, a red error appears in the console:



Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.


You scratch your head, open Postman, paste the same URL, click Send — and lo and behold, the data arrives! The server is working? It is. So why does the browser block the request?



This situation is a classic in web development. This question has gathered thousands of views on Stack Overflow. Today, we'll look under the hood and figure out why this happens, how CORS works, and how to fix it. Let's go!



What is CORS and Why is it Needed?



CORS (Cross-Origin Resource Sharing) is a browser security mechanism. It prevents JavaScript from one site (e.g., http://localhost:3000) from making requests to another (e.g., https://api.example.com), unless the server explicitly allows it.



Why? So that an attacker cannot steal data from another site through your browser. Without CORS, any script could read your email, bank accounts — a nightmare.



But there's a nuance: CORS only works in the browser. Postman, curl, server-side requests (Node.js, Python) — they don't check CORS. This is the first and main reason why Postman works, but JavaScript doesn't.



How CORS Works Under the Hood: In Simple Terms



When your JavaScript (e.g., fetch) makes a cross-origin request, the browser does two things:



  1. Checks the request type.
  2. If necessary, sends a preflight request (OPTIONS).


Simple Request vs Preflight



There are two types of cross-origin requests:



  • Simple request — if you use GET, POST, or HEAD, and only basic headers (Content-Type: text/plain, application/x-www-form-urlencoded, multipart/form-data). The browser sends the request and looks at the response header Access-Control-Allow-Origin.
  • Preflight request — if you use non-standard headers (e.g., Authorization), methods PUT/DELETE, or Content-Type: application/json. The browser first sends an OPTIONS request to ask: "Is it allowed to make such a request?"


Here's an example of a preflight in code:



fetch('https://api.example.com/data', {  method: 'POST',  headers: {    'Content-Type': 'application/json', // This triggers a preflight    'Authorization': 'Bearer my-token'  },  body: JSON.stringify({ key: 'value' })}).then(response => response.json()).then(data => console.log(data)).catch(err => console.error('CORS error:', err));


If the server does not respond to OPTIONS with the correct Access-Control-Allow-Origin header, the browser blocks the main request.



Why Does Postman Ignore CORS?



Postman is not a browser. It does not use the Same-Origin Policy. It simply sends an HTTP request and receives a response. It doesn't care where the request came from — it doesn't check CORS headers. The server can return anything, and Postman will show the response.



Therefore, when you test an API through Postman, you see that the server is working. But the browser requires the server to explicitly allow access from your domain.



How to Fix the CORS Error: 3 Real Ways



1. Configure the Server (The Right Way)



If you have access to the server, add the Access-Control-Allow-Origin header. For example, on Node.js with Express:



const express = require('express');const app = ex                

Blogs

Book Recommendations