DevLab
Text

CORS Explained: Why Your API Call is Blocked

Understand why browsers enforce the Same-Origin Policy, how CORS headers unlock cross-origin requests, and how to configure CORS correctly on your server.

What is the Same-Origin Policy?

Browsers enforce a rule: JavaScript on page A can only make network requests to the same origin (protocol + hostname + port). Without this policy, a malicious website could silently call your bank's API using your session cookies. CORS (Cross-Origin Resource Sharing) lets servers opt in to allowing specific cross-origin requests.

The CORS Flow

// Simple requests (GET/POST with basic headers):
Browser → GET https://api.example.com/data
          Origin: https://app.example.com

Server  → 200 OK
          Access-Control-Allow-Origin: https://app.example.com
// Browser sees the header → allows JS to read the response ✓

// Preflighted requests (DELETE, PUT, or custom headers):
Browser → OPTIONS https://api.example.com/data
          Access-Control-Request-Method: DELETE

Server  → 204 No Content
          Access-Control-Allow-Methods: GET, POST, DELETE
          Access-Control-Max-Age: 86400  // cache preflight 24h
// Then the actual DELETE is sent

Server Configuration

// Express.js
app.use(cors({
  origin: ['https://app.example.com'],
  methods: ['GET', 'POST', 'DELETE', 'PUT'],
  allowedHeaders: ['Authorization', 'Content-Type'],
  credentials: true,  // allow cookies
}));

// Manual headers (any server)
res.setHeader('Access-Control-Allow-Origin', 'https://app.example.com');
if (req.method === 'OPTIONS') { res.status(204).end(); return; }

The Wildcard + Credentials Trap

// Works for public APIs (no cookies)
Access-Control-Allow-Origin: *

// REJECTED by browsers — wildcard + credentials is invalid:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

// Correct — must specify exact origin when using credentials:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true

CORS is Browser-Only

CORS restrictions only apply to browser-based JavaScript. Server-to-server requests (curl, Node.js fetch, Postman) are never blocked by CORS. If an API call works in Postman but fails in the browser, it is a CORS configuration issue on the server — not a network or authentication problem.

More Learning Topics