Every web developer has stared at this infamous red error in the browser console:
Access to fetch at 'https://api.example.com/v1/transfer' from origin 'http://localhost:3000' has been blocked by CORS policyThe knee-jerk reaction is often to slap Access-Control-Allow-Origin: * onto the backend and move on. But first, ask yourself: Why does the exact same request work in Postman or cURL without any error, yet fail inside the browser?
Because CORS (Cross-Origin Resource Sharing) is not a server firewall—it is a browser security mechanism that protects the user.
1. Why Does the Same-Origin Policy (SOP) Exist?
By default, browsers enforce the Same-Origin Policy (SOP). Two URLs share the same origin only if their scheme (https), host (czay.dev), and port (443) match exactly.
Imagine a world without the Same-Origin Policy:
- You log into your bank (
https://bank.com), and your session cookie is stored in the browser. - In another tab, you open a malicious game or news site (
https://evil.com). - JavaScript running on
evil.comcould silently send afetch('https://bank.com/api/account')request in the background using your browser's cookies and read your private financial data.
SOP blocks evil.com from reading responses from bank.com.
2. How CORS Opens a Controlled Door
In modern web apps, your frontend (https://app.company.com) and backend API (https://api.company.com) often live on different origins. For the browser to permit this legitimate cross-origin call, the server must explicitly return an allowlist header:
Access-Control-Allow-Origin: https://app.company.com
Access-Control-Allow-Credentials: true3. Hidden Preflight OPTIONS Requests & Access-Control-Max-Age
Whenever your frontend sends a PUT, DELETE, or Content-Type: application/json request, the browser first sends a hidden OPTIONS (Preflight) request to ask the server for permission before sending the actual payload.
Firing a preflight request before every single API call doubles your network round-trip latency! You can eliminate repeated preflight requests by instructing the browser to cache the permission:
Access-Control-Max-Age: 86400With Access-Control-Max-Age: 86400, the browser caches the CORS preflight response for up to 24 hours, skipping redundant OPTIONS round-trips and significantly speeding up your frontend.
Interactive Roadmap & Tool
Read next
- CZENWhat Is a Circuit Breaker? Preventing Cascading Failures with Fail-Fast Architecture
What Is a Circuit Breaker? Preventing Cascading Failures with Fail-Fast Architecture
October 29, 2026 · 3 min read - CZENCutting Through the Noise: Which Backend Language and Framework Should You Choose in 2026?
Cutting Through the Noise: Which Backend Language and Framework Should You Choose in 2026?
October 25, 2026 · 4 min read