What is CORS?
CORS (Cross-Origin Resource Sharing) is the browser mechanism that decides whether a page on one origin may read a response from another. The server opts in with Access-Control-Allow-Origin and related headers; for requests with custom headers or non-simple methods the browser first sends an OPTIONS preflight. CORS protects users in browsers only — it does not restrict servers, curl or mobile apps.
- Web page
https://app.example.com - Browser
- API
api.example.com
- 1 From Web page To Browser: Calls the API with credentials Sends
AuthorizationandContent-TypePOST /v1/orders - 2 Browser internally: Preflight needed? Yes:
Authorizationand a JSONContent-Typeare outside the CORS-safelisted set - 3 From Browser To API: Preflight With
OriginplusAccess-Control-Request-MethodandAccess-Control-Request-HeadersOPTIONS /v1/orders - 4 From API To Browser: Preflight response reply A status and
Access-Control-Allow-*headers - 5 Browser internally: Checks the preflight Needs 2xx, both headers in
Allow-Headers,Allow-Credentials: trueandAllow-Originset to the exact origin, never* - 6 From Browser To API: Actual request Sent only if the preflight passed, with
Originand cookies orAuthorizationPOST /v1/orders - 7 From API To Browser: Response reply With its own
Access-Control-Allow-*headers - 8 Browser internally: Checks the response Needs
Allow-Credentials: trueandAllow-Originset to the exact origin, never* - 9 From Browser To Web page: The response, or a generic error reply If any check fails, the response stays hidden from the page
Outcome: In the example the API answers Access-Control-Allow-Origin: * and leaves Authorization out of Allow-Headers, so the verdict is Blocked. Fail
Per the Fetch Standard. A GET, HEAD or POST with only CORS-safelisted headers skips steps 3 to 5; Allow-Methods matters only for other methods. The tool’s relay sends both requests, and the tool applies these checks to their headers.
How to use CORS Tester
- Enter the public API URL and the origin of the web app that will call it.
- Select the method and list the request headers the app will send (Authorization, Content-Type…).
- Run the test and read the verdict; the "Why" list names the exact header that would block the browser.
- Fix the server configuration and re-run until the verdict is Allowed.
CORS Tester features
- Sends a preflight (OPTIONS) announcing your method and request headers, then the actual request with your chosen Origin
- Verdict explained step by step: origin match, credentials, allowed methods and headers, preflight status, max-age
- Detects when a preflight is required using the CORS-safelisted rules
- Tables of preflight and actual response headers with explanations
- Warns about wildcard-with-credentials and missing Vary: Origin
CORS Tester example
Test a credentialed POST (output shortened)
Input:
URL: https://api.example.com/v1/orders · Origin: https://app.example.com · Method: POST · Headers: Authorization, Content-TypeOutput:
Result: Blocked
Preflight needed: Yes (OPTIONS) · Preflight status: 204
Access-Control-Allow-Origin is "*" but the request is credentialed; browsers reject the wildcard with credentials.
Access-Control-Allow-Headers does not list: Authorization.Frequently asked questions about CORS Tester
When does a browser send a preflight?
For any method other than GET, HEAD or POST, and for request headers outside the CORS-safelisted set: Accept, Accept-Language, Content-Language, Content-Type only with application/x-www-form-urlencoded, multipart/form-data or text/plain, and Range only with a single bytes range. So Content-Type: application/json triggers one. The tool tells you whether your combination triggers OPTIONS; it receives header names only, so a Content-Type or Range you list is treated as a non-safelisted value. Leave it out to test a form or text/plain request.
Why is my request blocked even though Access-Control-Allow-Origin is *?
A wildcard is rejected when the request uses credentials (cookies or Authorization with credentials: "include"). Echo the exact origin, add Access-Control-Allow-Credentials: true and Vary: Origin instead.
Why does the tool call the API from a server instead of my browser?
A browser hides the blocked response, so you would only see a generic error. The relay performs the OPTIONS and actual requests with the Origin header you chose and returns the raw Access-Control-* headers so the verdict can be explained.
Can I test localhost or an internal API?
No. The relay refuses private, loopback and link-local addresses for safety. Expose the API through a tunnel (e.g. a public staging host) to test it.
Technical notes
The relay reproduces the browser algorithm from the Fetch Standard: the preflight is sent with Access-Control-Request-Method and Access-Control-Request-Headers, and the actual request with the Origin header. The server-side verdict is combined with a local re-evaluation so every reason is spelled out, including cases the relay treats as allowed but that fail for credentialed requests.
References
- Fetch StandardDefines CORS: preflight requests, the Access-Control-* headers and which responses a browser may expose to a page.
- Cross-Origin Resource Sharing (CORS) — MDNHow CORS works in practice: simple vs. preflighted requests, credentials, and the errors browsers report.