How HTTP Works

Tools

CORS Debugger

Will the browser let this page call that API? Describe the request and the server's CORS headers to get a verdict, the exact preflight, the console error you would see, and a server config that fixes it.

Try a scenario

1 · The browser request

Where your JavaScript runs. Scheme, host, port; no path or trailing slash.
ref
Comma separated names, e.g. Authorization, X-Custom.
Optional. Checks they are exposed, e.g. X-Total-Count, Location.

2 · The server response

ref
ref
ref
ref
URLs, exact origins, and header values are never included.

Result

Blockedpreflightedfails at OPTIONS preflight

Wildcard origin with credentials

When the request includes credentials (cookies, HTTP auth, client certs), Access-Control-Allow-Origin must be the exact origin, never *.

Why a preflight: PUT is not a CORS-safelisted method (only GET, HEAD, POST are); non-safelisted request header: authorization; Content-Type "application/json" is not one of application/x-www-form-urlencoded, multipart/form-data, text/plain.

Browser console error

Access to fetch at 'https://api.example.com/data' from origin 'https://myapp.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

How to fix it

Replace * with the exact origin (https://myapp.com), echoed from an allowlist, add Vary: Origin, and keep Access-Control-Allow-Credentials: true.

Preflight (OPTIONS)
> OPTIONS /data HTTP/1.1
> Host: api.example.com
> Origin: https://myapp.com
> Access-Control-Request-Method: PUT
> Access-Control-Request-Headers: authorization,content-type
>
< HTTP/1.1 204 No Content
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Methods: GET, POST
< Access-Control-Allow-Headers: Content-Type
< Access-Control-Max-Age: 86400
<
The browser sends this automatically before your request. See Access-Control-Request-Method.

Server config that works for this request

Generated from the request above (origin, method, headers, credentials) and clamped to what browsers honour. Answer OPTIONS before authentication.

import cors from 'cors' // Register BEFORE auth middleware so OPTIONS preflights are not rejected. app.use(cors({ origin: ['https://myapp.com'], // exact origins from an allowlist methods: ['GET', 'POST', 'PUT'], allowedHeaders: ['content-type', 'authorization'], credentials: true, maxAge: 7200, optionsSuccessStatus: 204, }))

CORS reference

Read the CORS guide for how cross-origin requests work end to end, or the compare page CORS vs CSP. Header references: Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Max-Age, Access-Control-Request-Method, Access-Control-Request-Headers, Origin and Vary.

Browse /search