How to use it
- Choose the server and whether to allow only listed origins or any origin.
- Enter the origins exactly as the browser sends them: scheme, host and port, no trailing path. A trailing slash is removed.
- 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.