CORS Header Tester (Preflight Simulator)
CORS errors are the #1 confusing fetch() error: the browser blocks the response but your server is returning 200 OK with the data. The trick is that CORS rules are enforced by the browser, not the server — the server only sets headers, and the browser decides whether to expose the response to JS. This tool simulates exactly that decision: you input the request origin, method, and headers, plus the server's response headers, and it tells you whether a real browser would allow the request — and which header is missing if not.
Request (browser side)
Server response headers
How to use the CORS Header Tester (Preflight Simulator)
Fill in the request (what your browser sends): the Origin header, HTTP method, custom headers, credentials mode. Then paste the server's response headers (use a tool like curl -v or browser DevTools → Network → Response Headers to grab them).
The tool checks each rule the browser enforces and lists what would pass / fail. If preflight is required (it usually is for POST + custom headers), it shows that step separately.
About CORS Header Tester (Preflight Simulator)
CORS (Cross-Origin Resource Sharing) is the W3C standard that lets browsers selectively relax the same-origin policy. By default, a page at https://app.example.com cannot read responses from https://api.example.com via fetch / XHR. The server can opt-in by sending response headers like Access-Control-Allow-Origin: https://app.example.com, telling the browser "this origin is allowed to read this response."
Two flavors:
- Simple requests (GET/HEAD/POST with safe content types and no custom headers) — the browser sends the request directly, then checks the response's
Access-Control-Allow-Origin. - Preflighted requests (everything else — PUT/DELETE/PATCH, custom headers like
Authorization, content type other thanapplication/x-www-form-urlencoded) — the browser sends anOPTIONSpreflight first, asking "may I send method X with headers Y from origin Z?" If the server's preflight response allows it, the actual request goes out.
Credentials add complexity: credentials: "include" (cookies / Authorization sent cross-origin) requires Access-Control-Allow-Credentials: true AND Access-Control-Allow-Origin must be a specific origin (not *).
Common use cases
- "Why is my fetch() failing?" — paste your request and server's headers, get a specific reason.
- Configuring a new API — work out exactly which CORS headers you need.
- Debugging preflight failures — many people miss that
OPTIONSneeds the same CORS headers as the actual request. - Verifying production matches dev — copy headers from prod and dev side-by-side.
- Auditing CORS for security — checking that a permissive origin (
*) isn't leaking sensitive data.
Frequently asked questions
Does this make actual HTTP requests?
curl -H "Origin: ..." -v https://api.example.com/path.When is OPTIONS preflight required?
Accept, Content-Language) are sent, OR when Content-Type is anything other than the three safelisted forms.Why does my API allow Origin: * but credentials still fail?
Access-Control-Allow-Origin: * when Access-Control-Allow-Credentials: true. The browser refuses this combination by spec.Is OPTIONS request cacheable?
Access-Control-Max-Age: N (seconds) tells the browser how long to cache the preflight response. Chrome caps this at 7200, Firefox at 86400.