Browser blocks fetch from api.example.com when page is on app.example.com — why does the same code work in curl but not in browser?
Per Wikipedia: “CORS is a browser security mechanism that blocks cross-origin requests unless server sends Access-Control-Allow-Origin headers.”
CORS is the bouncer checking the guest list — same-origin is allowed in, cross-origin needs explicit invite from server.
- Browser sends Origin header
- Server checks allow list
- Server replies with ACAO header if allowed
- Browser enforces — blocks if missing
- Preflight OPTIONS for non-simple requests
- Only enforced by browsers, not by curl
- Simple GET/POST may skip preflight
- Credentials need explicit Allow-Credentials
fetch('https://api.example.com/data', {mode: 'cors'})
.then(r => r.json())- Wildcard * with credentials fails — must list origin
- Caching preflight without Vary: Origin causes leaks