CORS
Cross-Origin Resource Sharing · /kɔːrz/
CORS is the browser-enforced rule that decides whether JavaScript on one origin is allowed to read a response from another. It's not a network-level filter — the request still goes through; the browser just refuses to hand the body to your code unless the response carries the right Access-Control-Allow-Origin header.
When does it kick in?
Any time your page on https://app.example.com tries to fetch() (or XMLHttpRequest) from a different origin. "Different" means a different scheme, host, or port. Subdomains count: app.example.com and api.example.com are different origins.
What doesn't trigger CORS:
curl, server-to-server requests, and mobile apps — only browsers enforce it.- Same-origin requests — your page calling its own backend on the same host.
<img>,<script>, and<link>tags loading cross-origin assets. They're allowed to display the resource, just not let JS read its bytes.
The two flavors
Simple requests (GET/POST/HEAD with no custom headers and a "safe" Content-Type) — the browser sends the request first, then checks the response. If the right Access-Control-Allow-Origin isn't there, your JS gets a network error in the console but the side effects (counters, logs, even a destructive POST) already happened on the server.
Preflighted requests (anything else — PUT/DELETE, JSON bodies, custom headers like Authorization) — the browser first sends a preflight OPTIONS asking the server "can my origin do this?". The real request only goes if the preflight allows it.
Why it exists
Before CORS, browsers enforced the same-origin policy strictly: cross-origin reads were impossible. That breaks any API integration. CORS is the structured way for a server to say "yes, this specific other origin is allowed to read me," without opening the door to every site on the internet.
How to fix CORS errors
Three ways, in order of correctness:
- Configure the server to send
Access-Control-Allow-Originfor your origin. See the full how-to with code in Node, Go, and Python. - Proxy through your own backend. Browser → your server (same origin) → upstream. No cross-origin call from the browser at all.
- Use a CORS proxy like corsproxy.dev when you don't control the upstream. The proxy returns the response with the right headers.
Common questions
Does CORS make my API secure? No. CORS is a browser-side rule that decides what one user's browser can read on another origin. It doesn't authenticate anything. Server-side auth (cookies, bearer tokens, signatures) is what makes your API safe.
If CORS is browser-only, why does my server need to do anything? Because the browser asks the server whether the response can be shared. The server's reply is what unblocks the browser. There's no way to tell the browser "trust me" from JS.