🌐 CORS Header Builder
Build the Access-Control-* response headers your server needs to send to allow
cross-origin requests from another site.
What the builder writes
The five fields map straight onto five response headers. Nothing is sent anywhere - the text is assembled in your browser, and you paste it into your server config. With the defaults you get:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Ticking Allow Credentials adds
Access-Control-Allow-Credentials: true. The tool flags the one
combination browsers reject outright: credentials together with an origin of
*.
Where these headers go wrong
- The origin header takes one value. It is a single origin or
*- never a comma-separated list. To support several sites, match the request'sOriginagainst your own allowlist and echo back the one that matched, then sendVary: Originso caches keep the answers apart. - Max-Age is a request, not a promise. Chromium clamps preflight caching to 7200 seconds, so the 86400 above becomes two hours there.
- Reading a custom response header needs one more.
Access-Control-Expose-Headersis not produced here; without it JavaScript sees only the handful of headers browsers expose by default.
Frequently asked questions
Can I allow more than one origin?
Not in a single static header. Keep an allowlist server-side, compare the
incoming Origin value against it, and return that exact string.
Add Vary: Origin or a cache will hand one site another site's
header.
Why does my preflight still fail after adding these headers?
The OPTIONS request has to be answered by the server with a 2xx
and these headers before any authentication runs - a preflight carries no
cookies or auth header. Also check that every header the browser names in
Access-Control-Request-Headers appears in your allow list.
Is Access-Control-Allow-Origin: * a security problem?
For genuinely public, unauthenticated data, no. It becomes one when the same endpoint returns per-user data behind a cookie or bearer token, which is why browsers refuse the wildcard once credentials are allowed.