CORS Explained
CORS (Cross-Origin Resource Sharing) is the browser's same-origin firewall. If your JS at site A wants to `fetch()` from site B, the browser asks B's permission via CORS headers.
1 credit
Same-origin rule
- Origin = scheme + host + port. `https://a.com:443` and `http://a.com:80` are different origins.
- By default, browser JS can't read responses from cross-origin fetches.
- CORS is a BROWSER check — servers always receive the request. It's the RESPONSE that gets blocked client-side.
- This doesn't apply server-to-server (no browser involved) or `<img>` / `<link>` / `<script>` — those have separate rules.
Simple requests
- GET / POST / HEAD with default headers and `Content-Type` of `text/plain`, `application/x-www-form-urlencoded`, or `multipart/form-data`.
- Browser sends request directly; server responds with `Access-Control-Allow-Origin: <origin>` or `*`.
- If header is absent/wrong, browser hides the response from JS.
Preflighted requests
- Triggered by: PUT/DELETE, custom headers (Authorization, X-*), JSON content type.
- Browser sends `OPTIONS` first. Server must respond with allowed methods/headers.
- Successful preflight gets cached per `Access-Control-Max-Age` (3600 is reasonable).
Server headers
6 itemsAccess-Control-Allow-Origin
`*` (anyone) or exact origin (echo if allow-listed)Access-Control-Allow-Credentials
`true` if you send cookies; CAN'T combine with `*` originAccess-Control-Allow-Methods
Preflight response: `GET, POST, PUT, DELETE`Access-Control-Allow-Headers
Preflight response: `Content-Type, Authorization`Access-Control-Expose-Headers
Which response headers JS can read (everything else is hidden)Access-Control-Max-Age
Seconds to cache the preflightGotchas
- `Access-Control-Allow-Origin: *` + `credentials: include` fetch = spec-forbidden. Browser blocks.
- Localhost vs 127.0.0.1 are different origins. Stick to one.
- Wildcards (`https://*.mysite.com`) are NOT supported — you must echo the origin.
- CORS errors have confusing messages; always check the actual response headers in devtools Network tab.