CORS Policy Tester Tool - Preflight and Access-Control Header Simulator

First Published:
Last Updated:

Stop guessing why a cross-origin request fails. Describe the request your browser would send (Origin, method, headers, Content-Type, and whether credentials are included) and the Access-Control-* headers your server returns, and this tool decides — using the CORS specification logic from MDN and the WHATWG Fetch Standard — whether a preflight is required and whether the browser would expose the response to JavaScript. It explains every step. No request is ever sent: the verdict comes from specification rules, entirely in your browser.

All processing is performed entirely in your browser using client-side JavaScript. No data is transmitted to any server. Your origins, headers, and policy values never leave your device.

  • This tool is provided "AS IS" without any warranties of any kind.
  • The author accepts no responsibility for incorrect verdicts — CORS behavior can differ slightly between browsers and over time.
  • This tool models the common cases of the specification and does not send any network request, so it cannot observe your server's real behavior.
  • Always confirm edge cases against your browser's DevTools Network tab and the official specifications.
  • By using this tool, you accept full responsibility for any outcomes.

Privacy: This tool uses client-side JavaScript for all processing. No data is transmitted to servers, no information is uploaded online, all processing happens locally in your browser. Once loaded, this tool continues to work even without an internet connection. For more details, please refer to our Web Tools Disclaimer.

Request (what the browser sends)

The scheme + host + optional port of the page making the request. No trailing slash or path.
Do not list Content-Type here (use the field above). Author-set headers outside the CORS-safelisted set trigger a preflight.

Server CORS Response Headers

Features

  • Specification-based verdict: Decides Allow or Block from the CORS rules in MDN and the WHATWG Fetch Standard — no network request is ever made.
  • Preflight detection: Tells you whether the browser sends an OPTIONS preflight and exactly which condition (non-safelisted method, header, or Content-Type) triggers it.
  • Step-by-step explanation: Separate cards for "preflight required?", "preflight satisfied?", and "response exposed to JavaScript?", each with per-check pass/fail reasons.
  • Credentials-aware: Enforces the rules that Access-Control-Allow-Origin: * is forbidden with credentials, that Access-Control-Allow-Credentials: true is required, and that * becomes a literal value for methods and headers.
  • Authorization gotcha: Knows that the Authorization header is never covered by the * wildcard and must always be listed explicitly.
  • Minimal header generator: Produces the smallest Access-Control-* response that satisfies your request, ready to copy.
  • Three worked examples: Simple GET, a preflighted JSON POST, and the classic credentials-plus-wildcard failure.
  • Client-side only: Works offline once loaded; nothing you type leaves your browser.

How to Use

  1. Fill in the Request fields: the page Origin, the HTTP method, the Content-Type (if the request has a body), any extra request headers, and whether credentials are included.
  2. Fill in the Server CORS Response Headers as your server returns them (Access-Control-Allow-Origin, -Allow-Methods, -Allow-Headers, the -Allow-Credentials checkbox, and optional -Max-Age / -Expose-Headers).
  3. Click Evaluate (or press Ctrl/+Enter). The verdict and steps also refresh automatically as you edit.
  4. Read the overall Allow/Block verdict, then work through each step to see why.
  5. Use Copy Headers to grab the suggested minimal policy, or Load an example to compare against your own scenario.

About This Tool

Cross-Origin Resource Sharing (CORS) is the browser mechanism that lets a server relax the same-origin policy and permit a page from one origin to read responses from another. The browser classifies a cross-origin request as either a simple request, which is sent directly, or a request that first needs a preflight — an automatic OPTIONS call carrying Access-Control-Request-Method and Access-Control-Request-Headers — that the server must approve before the real request is sent.

A request is "simple" only when the method is GET, HEAD, or POST; every manually-set header is CORS-safelisted (Accept, Accept-Language, Content-Language, Content-Type, Range, within value constraints); and the Content-Type is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain. Anything else triggers a preflight. After the request, the browser only exposes the response to JavaScript if Access-Control-Allow-Origin matches the origin (and, for credentialed requests, only if it echoes the exact origin together with Access-Control-Allow-Credentials: true).

This tester encodes those rules so you can reason about a scenario without deploying anything. The rules were verified against the MDN CORS documentation and the WHATWG Fetch Standard on 2026-06-23.

Sources: MDN — Cross-Origin Resource Sharing (CORS), MDN — Access-Control-Allow-Headers, WHATWG — Fetch Standard.

Frequently Asked Questions

What triggers a preflight request?

A preflight (OPTIONS) is sent whenever the request is not "simple": the method is something other than GET/HEAD/POST, the request sets any header outside the CORS-safelisted set (for example X-Api-Key or Authorization), or the Content-Type is not one of the three safelisted values (so application/json triggers one).

Why does Access-Control-Allow-Origin: * fail with credentials?

When a request is sent with credentials (cookies, HTTP authentication, or client certificates), the specification forbids the wildcard. The server must echo the exact requesting origin in Access-Control-Allow-Origin and also return Access-Control-Allow-Credentials: true; otherwise the browser blocks the response. With credentials, * is likewise treated as a literal value for Access-Control-Allow-Methods and Access-Control-Allow-Headers.

What is the difference between a simple request and a preflighted request?

A simple request meets all of the safelist conditions (method, headers, and Content-Type) and is sent straight to the server; the browser applies the CORS check only to the response. A preflighted request fails at least one condition, so the browser first asks permission with an OPTIONS call and only sends the real request if that preflight is approved.

What is Access-Control-Max-Age?

Access-Control-Max-Age is the number of seconds the browser may cache a successful preflight result for the same method and headers, so repeated calls skip the extra OPTIONS round trip. It is informational here and does not change the Allow/Block verdict; browsers also enforce their own upper cap on the value.

Why is my request blocked even though the server returned 200?

CORS is enforced by the browser, not the server. The server can happily process the request and return 200, but if the response lacks a matching Access-Control-Allow-Origin (or the required credentials headers), the browser refuses to expose the response to your JavaScript — which surfaces as a CORS error even though the network call succeeded.

Related Tools

Important Notes

  • This tester evaluates CORS outcomes using the specification logic (MDN / Fetch Standard) as of 2026-06-23, without making any network request. It models the common cases and may not capture every browser-specific nuance. Verify against your browser's actual behavior for edge cases.
  • The tool models one set of server response headers applied to both the preflight and the actual response. In production, your server must return the matching Access-Control-* headers on both the OPTIONS preflight and the actual response.
  • Header-value constraints for safelisting (such as the 128-byte value limit and disallowed characters) are approximated; unusual values may behave differently in a real browser.
  • Browser-set or forbidden request headers (for example Host, Connection, Cookie, or Sec-/Proxy- prefixed names) cannot be set from JavaScript and are not modeled as preflight triggers here.
  • The tool does not evaluate private-network access preflights, opaque (no-cors) responses, or redirect handling, which follow additional rules.
  • Access-Control-Expose-Headers only controls which response headers JavaScript can read; it does not affect whether the request itself is allowed.

References:
Tech Blog with curated related content
Web Tools Collection

Written by Hidekazu Konishi