CORS Header Generator
Build the Access-Control response headers for your API from a form: allowed origin, methods, headers, exposed headers, credentials and max-age.
Choose the origin, methods, request headers, exposed headers, credentials setting and max-age, and get the corresponding Access-Control headers to add to your server. The generator also refuses the combinations the specification forbids, before your browser does.
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Max-Age: 86400
// CORS Header Generator: Features
CORS is enforced by the browser, configured on the server
This is the point that causes most confusion. A CORS error appears in the browser console, so it looks like a client problem, but nothing in the client can fix it. The browser makes the request, sees that the response lacks the headers permitting your origin to read it, and blocks your code from seeing the result. The request may well have succeeded. The fix always belongs on the server that produces the response.
Wildcard and credentials cannot be combined
Setting the allowed origin to an asterisk while also allowing credentials is explicitly forbidden, and browsers reject the response outright. The reason is straightforward: it would let any site on the internet make authenticated requests as the logged-in user and read the answers. The generator reports this combination rather than producing headers that will fail, because the browser error message does not always make the cause obvious.
The preflight request
For anything beyond a simple request, the browser first sends an OPTIONS request asking whether the real one is permitted. Your server has to answer that OPTIONS request with the Access-Control headers and a success status; returning 404 or 405 for OPTIONS is a common cause of CORS failures in APIs that otherwise look correctly configured. A custom header, a content type of application/json, or any method beyond GET, HEAD and POST all trigger a preflight.
Why a response header is invisible to your code
By default, JavaScript can read only a short list of response headers. Anything else, including a pagination header, a rate-limit header or a custom correlation identifier, has to be named in Access-Control-Expose-Headers before your code can see it. The header is present in the response, and the browser hides it. This catches people out regularly because the header is clearly visible in the network tab while being undefined in code.
Max-age caches the permission, not the response
Setting a max-age lets the browser skip the preflight for subsequent requests to the same endpoint for that many seconds, which removes a round trip from every call. Browsers cap the value well below whatever you set, and the cache is keyed to the specific combination of origin, method and headers. It is worth setting during normal operation and worth setting to zero while you are actively debugging, so that changes take effect immediately. For restricting where a page may load resources from, which is a separate concern, see the CSP Generator.
// CORS Header Generator: FAQ
What headers does it produce?
- The Access-Control response headers matching your choices: allowed origin, allowed methods, allowed request headers, exposed response headers, the credentials flag and max-age. Add them to the responses your server sends, including to the preflight OPTIONS request.
Why am I getting a CORS error?
- Because the response does not carry headers permitting your page's origin to read it. The usual causes are no CORS headers at all, an allowed origin that does not exactly match yours including scheme and port, an OPTIONS request that the server answers with an error, or a request header your configuration does not permit.
Can I just allow all origins?
- You can for a genuinely public API with no authentication, and it is the right choice there. You cannot if the endpoint uses cookies or authorization headers, both because the specification forbids combining the wildcard with credentials and because it would let any site read authenticated responses on behalf of your users.
Why does my custom response header not appear in JavaScript?
- Because it is not listed in Access-Control-Expose-Headers. Browsers expose only a small default set, and everything else is hidden from script even though it arrives in the response and is visible in the network tab. Name the header explicitly to make it readable.
What triggers a preflight request?
- Any method other than GET, HEAD or POST; any request header beyond the small safelisted set, which includes a custom header or an Authorization header; and a Content-Type other than the three simple form types, so a JSON body triggers one. In practice most API calls from a browser are preflighted.
Why does my API work in curl but not in the browser?
- Because curl does not implement CORS. It is a browser security mechanism, so a command-line client simply makes the request and reads the response. That difference is the clearest sign that what you are seeing is a CORS problem rather than a broken endpoint.
Should the origin include the port?
- Yes, and the scheme too. An origin is the scheme, host and port together, so http://localhost:3000 and http://localhost:5173 are different origins, as are the http and https versions of the same host. The match must be exact; a trailing slash will also break it.
What value should max-age have?
- Something on the order of an hour is reasonable in production, and it removes a preflight round trip from most requests. Browsers enforce their own upper limits regardless of what you set. Set it to zero while debugging, so that configuration changes take effect without waiting for a cached permission to expire.
Does adding these headers make my API less secure?
- Adding them deliberately for a known origin does not. Setting the wildcard on an authenticated endpoint does, and combining a permissive origin with credentials is forbidden precisely because of that. Name the origins you intend to serve rather than opening it up to make an error go away.
Is the configuration I build sent to a server?
- No. The headers are assembled in your browser from the options you choose, and nothing you enter is transmitted, stored or logged.
// How to Use CORS Header Generator
-
Set the allowed origin
Enter the exact origin that will call your API, including the scheme and port, or choose the wildcard for a public unauthenticated endpoint. Remember that the match is exact and a trailing slash breaks it.
-
Choose methods, headers and options
Select the HTTP methods your endpoint accepts and any request headers your client sends, such as Authorization or a custom header. Name any response headers your JavaScript needs to read, and set credentials and max-age as required.
-
Copy the headers to your server
Copy the generated headers and add them to your responses, including to the preflight OPTIONS request, which must also return a success status. If the generator reports a conflict, fix that before deploying: the browser would reject the same combination.
Category Security