CORS header generator

List the sites allowed to call your API, the methods and headers they use and whether cookies are sent. The generator writes the Access-Control-Allow-Origin logic for one or several origins, the other CORS headers and a 204 answer to preflight requests.

Allowed origins
Scheme, host and optional port, separated by commas or spaces: https://app.example.com, http://localhost:3000
Headers the browser may send, such as Content-Type or Authorization.
Response headers JavaScript may read beyond the basic ones, such as X-Total-Count. Leave empty if none.
How long the browser may reuse a preflight answer. Leave empty to omit.

nginx: the map block goes in http {}, the rest in your server or location. Apache: needs mod_headers, mod_setenvif and mod_rewrite. Node.js: call cors(req, res) first and stop if it returns true.

Runs in your browser: nothing you enter is sent anywhere.

How to use it

  1. Choose the server and whether to allow only listed origins or any origin.
  2. Enter the origins exactly as the browser sends them: scheme, host and port, no trailing path. A trailing slash is removed.
  3. Adjust methods, request headers, exposed headers, credentials and the preflight cache time, then copy the configuration.

How CORS works

The browser adds an Origin header to cross-site requests. The response must carry Access-Control-Allow-Origin with that origin (or *), or JavaScript cannot read it. For non-simple requests a preflight OPTIONS request comes first and must be answered with the allowed methods and headers.

Header Meaning
Access-Control-Allow-Origin The one origin allowed to read the response, or *
Access-Control-Allow-Methods Methods allowed in the real request
Access-Control-Allow-Headers Request headers the client may send
Access-Control-Expose-Headers Response headers JavaScript may read
Access-Control-Allow-Credentials true to allow cookies and HTTP auth
Access-Control-Max-Age Seconds the preflight answer may be cached

Worked example

Origins https://example.com and https://app.example.com for nginx. Because there are two, the generator writes a map that copies the request’s Origin into $cors_origin only when it is on the list:

map $http_origin $cors_origin {
    default "";
    "https://example.com" $http_origin;
    "https://app.example.com" $http_origin;
}

Inside location / it then sends Access-Control-Allow-Origin $cors_origin, Vary: Origin, the methods, the headers and Access-Control-Max-Age 86400, and answers OPTIONS with return 204.

Common mistakes

  • A path or trailing slash in the origin. The browser sends https://example.com, never https://example.com/ or https://example.com/api.
  • Forgetting Vary: Origin when the allowed origin changes per request: a CDN may then serve one site’s answer to another.
  • Adding CORS headers in two places (the app and the proxy). Two Access-Control-Allow-Origin headers make the browser reject the response.

Frequently asked questions

How do I allow several origins?

Access-Control-Allow-Origin can hold only one origin or *. The server must compare the request's Origin header with its list and send that origin back when it matches, plus Vary: Origin so caches keep the answers apart. The generated nginx map, Apache SetEnvIf rule and Node.js check do exactly this.

Why can't I use * with credentials?

The Fetch standard forbids it: when a request carries cookies or HTTP authentication, the browser only accepts a response that names the exact origin. With * and credentials the browser blocks the response.

What is a preflight request?

For requests other than simple GET, HEAD or form POSTs, for example with JSON bodies or an Authorization header, the browser first sends an OPTIONS request asking which methods and headers are allowed. The server answers it with the CORS headers and an empty 204 response; Max-Age lets the browser cache that answer.

Does CORS protect my API?

No. CORS only tells browsers which other sites may read your responses. Scripts on servers and tools such as curl ignore it. Authentication and authorisation still have to be checked on every request.

Do I need to list Content-Type in allowed headers?

Yes, if clients send JSON. Content-Type is only free when it is text/plain, multipart/form-data or application/x-www-form-urlencoded; application/json triggers a preflight that must allow it.

More in Developer

All tools in this category: Developer ·Updated November 7, 2026

Privacy choices

Google Analytics shows us which tools are used and whether they work. It may set cookies. Your choice is kept in this browser.