{ CORS Header Generator }

// configure CORS headers visually for any backend

Build CORS headers visually. Configure Access-Control-Allow-Origin, methods, headers, credentials, preflight, and get output for .htaccess, Nginx, Express, PHP, and more. Free, no signup.

Quick Presets:
ALLOWED ORIGINS

Add each allowed origin separately. https:// scheme required.

ALLOWED METHODS
ALLOWED REQUEST HEADERS
EXPOSED RESPONSE HEADERS Headers JS can read
CREDENTIALS & PREFLIGHT
Max-Age (preflight cache)
seconds

        
// RESPONSE HEADERS GENERATED
// CORS REQUEST FLOW

HOW TO USE

  1. 01
    Configure origins

    Choose a mode: specific origins (recommended), wildcard for public APIs, or dynamic reflection for multi-origin apps with credentials. Add each allowed origin.

  2. 02
    Set methods and headers

    Toggle which HTTP methods to allow. Add the request headers your API accepts (like Content-Type and Authorization). Add any response headers JavaScript should be allowed to read.

  3. 03
    Copy your backend code

    Switch between output formats (.htaccess, Nginx, Express.js, PHP, Flask, Spring) and copy the ready-to-use implementation for your stack.

WHY CORS EXISTS

The Same-Origin Policy prevents scripts on app.com from reading responses from api.com. CORS is the mechanism that lets api.com explicitly grant permission to app.com. The server adds Access-Control-Allow-Origin response headers — the browser checks them and allows or blocks the JavaScript from reading the response.

SIMPLE VS PREFLIGHT

Simple requests (GET/HEAD/POST with standard headers) are sent directly. All other requests trigger a preflight: an OPTIONS request that asks the server if the actual request is allowed. The server's OPTIONS response (with CORS headers) determines whether the browser proceeds with the real request.

COMMON MISTAKES

  • 🚫 Using * with credentials: true — browsers block this combination
  • 🚫 Forgetting OPTIONS method in allowed methods
  • 🚫 Not listing Authorization in Access-Control-Allow-Headers
  • 🚫 Setting CORS headers in the wrong server block (nginx)
  • 🚫 Reflecting any origin without validating against an allowlist
  • ✅ Always validate reflected origins against a hard-coded allowlist

FREQUENTLY ASKED QUESTIONS

Why can't I use wildcard * with credentials?

The Access-Control-Allow-Origin: * wildcard tells the browser "any origin is allowed". For security reasons, browsers refuse to include cookies or authorization headers when the origin is a wildcard — because that would allow any malicious website to make authenticated requests on behalf of your users. To use credentials, you must specify the exact origin (or dynamically reflect it from a validated allowlist).

What is a preflight request and when does it happen?

A preflight is an automatic OPTIONS request that the browser sends before the actual request. It happens when: the method is anything other than GET, HEAD, or POST; the Content-Type is not one of the three simple types; or custom headers are included. The server must respond to the preflight with CORS headers. If your server doesn't handle OPTIONS requests, all non-simple CORS requests will fail.

What does Access-Control-Expose-Headers do?

By default, JavaScript can only read the response headers: Cache-Control, Content-Language, Content-Length, Content-Type, Expires, and Last-Modified. If your API returns custom headers like X-Rate-Limit-Remaining or X-Request-ID that you want JavaScript to read, you must explicitly list them in Access-Control-Expose-Headers.

What is "dynamic" origin mode?

Dynamic (or "reflective") CORS reflects the incoming Origin header back in the Access-Control-Allow-Origin response — but only after validating it against a hard-coded allowlist. This allows multiple specific origins to use credentials, which the wildcard * cannot. The server code checks if the requesting origin is in the approved list and echoes it back; otherwise it omits the header and the browser blocks the request.

What is Max-Age for preflight?

Access-Control-Max-Age tells the browser how long (in seconds) to cache the preflight response. During this time, repeated non-simple requests to the same endpoint don't need a preflight. Setting it to 0 disables caching (every request preflights). The browser maximum is often 600 seconds (Chrome) or 86400 seconds (Firefox). Higher values reduce latency from repeated preflight checks.

Do CORS headers need to be on every response?

Yes. CORS headers must be present on every response that will be read by cross-origin JavaScript — not just preflight responses. A common mistake is adding CORS headers only to the OPTIONS response. The actual GET/POST/etc. response also needs Access-Control-Allow-Origin (and Access-Control-Allow-Credentials if using credentials) or the browser will block the JavaScript from reading the response.

CORS Header Generator — Configure Cross-Origin Resource Sharing for Any Backend

CORS errors are among the most frustrating issues in web development — the browser silently blocks the request and the only clue is a cryptic console message. Getting CORS right requires understanding five different response headers and their interactions, knowing when preflight requests trigger, and correctly handling the credentials/wildcard incompatibility. This generator handles all of that complexity and outputs ready-to-use code for your specific backend.

Understanding the CORS Headers

Access-Control-Allow-Origin is the most important header — it specifies which origins may read the response. Access-Control-Allow-Methods lists the permitted HTTP methods. Access-Control-Allow-Headers lists the request headers the browser is allowed to send. Access-Control-Allow-Credentials enables cookie and auth header forwarding. Access-Control-Max-Age caches the preflight response. Access-Control-Expose-Headers makes custom response headers readable to JavaScript.

Security Considerations

Never blindly reflect any incoming Origin header without validating it. A server that echoes any origin provides the same security posture as Access-Control-Allow-Origin: * but makes the weakness less obvious. Always validate against a hard-coded allowlist. Also be careful with Vary: Origin — when using origin reflection, you must include this header to prevent caching systems from serving one origin's response to a different origin.