Skip to content
๐ŸŒ

CORS Header Generator

Developer

Generate Cross-Origin Resource Sharing (CORS) headers for your web server.

0
0
Scenario
Allowed Origins
https://example.com
Allowed Methods
Allowed Headers
Exposed Headers
X-RateLimit-RemainingX-RateLimit-Reset
Preflight Max Age (seconds)
CORS Headers Preview
Access-Control-Allow-Origin:https://example.com
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers:Content-Type, Authorization
Access-Control-Expose-Headers:X-RateLimit-Remaining, X-RateLimit-Reset
Access-Control-Max-Age:86400
Nginx Configuration
# Nginx CORS Configuration

location / {
    set $access_control_allow_origin "https://example.com";
    add_header Access-Control-Allow-Origin "$access_control_allow_origin" always;
    add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS" always;
    add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
    add_header Access-Control-Expose-Headers "X-RateLimit-Remaining, X-RateLimit-Reset" always;
    add_header Access-Control-Max-Age "86400" always;

    # Handle preflight requests
    if ($request_method = OPTIONS) {
        add_header Access-Control-Allow-Origin "$access_control_allow_origin" always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
        add_header Access-Control-Expose-Headers "X-RateLimit-Remaining, X-RateLimit-Reset" always;
        add_header Access-Control-Max-Age "86400" always;
        add_header Access-Control-Allow-Credentials "true" always;
        add_header Content-Length 0;
        add_header Content-Type text/plain;
        return 204;
    }
}
Apache Configuration
# Apache CORS Configuration

<IfModule mod_headers.c>
    # CORS Headers
    Header set Access-Control-Allow-Origin "https://example.com"
    Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS"
    Header set Access-Control-Allow-Headers "Content-Type, Authorization"
    Header set Access-Control-Expose-Headers "X-RateLimit-Remaining, X-RateLimit-Reset"
    Header set Access-Control-Max-Age "86400"

    # Handle preflight requests
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} OPTIONS
    RewriteRule ^(.*)$ $1 [R=200,L]
</IfModule>
Express.js
// Express.js CORS Middleware Configuration

const cors = require('cors');

const corsOptions = {
  origin: ['https://example.com'],
  methods: ["GET","POST","PUT","DELETE","PATCH","OPTIONS"],
  allowedHeaders: ["Content-Type","Authorization"],
  exposedHeaders: ["X-RateLimit-Remaining","X-RateLimit-Reset"],
  credentials: false,
  maxAge: 86400,
};

app.use(cors(corsOptions));

// Or with more control:
app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (config.allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }
  if (false) {
    res.setHeader('Access-Control-Allow-Credentials', 'true');
  }
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.setHeader('Access-Control-Expose-Headers', 'X-RateLimit-Remaining, X-RateLimit-Reset');
  res.setHeader('Access-Control-Max-Age', '86400');

  if (req.method === 'OPTIONS') {
    return res.status(204).end();
  }
  next();
});
Next.js
// Next.js API Route CORS Configuration

import { NextResponse } from 'next/server';

const corsOptions = {
  origin: ['https://example.com'],
  methods: ["GET","POST","PUT","DELETE","PATCH","OPTIONS"],
  allowedHeaders: ["Content-Type","Authorization"],
  exposedHeaders: ["X-RateLimit-Remaining","X-RateLimit-Reset"],
  credentials: false,
};

export function middleware(request: Request) {
  const response = NextResponse.next();

  // CORS headers
  response.headers.set('Access-Control-Allow-Origin', request.headers.get('origin') || '');
  
  response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
  response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  response.headers.set('Access-Control-Expose-Headers', 'X-RateLimit-Remaining, X-RateLimit-Reset');
  response.headers.set('Access-Control-Max-Age', '86400');

  return response;
}

export const config = {
  matcher: '/api/:path*',
};
Django
# Django CORS Configuration

# Install: pip install django-cors-headers

# settings.py
INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...
]

CORS_ALLOW_ALL_ORIGINS = false
CORS_ALLOWED_ORIGINS = ['https://example.com']
CORS_ALLOW_METHODS = ["GET","POST","PUT","DELETE","PATCH","OPTIONS"]
CORS_ALLOW_HEADERS = ["content-type","authorization"]
CORS_EXPOSE_HEADERS = ["X-RateLimit-Remaining","X-RateLimit-Reset"]
CORS_ALLOW_CREDENTIALS = false
CORS_PREFLIGHT_MAX_AGE = 86400

# Or in middleware.py for more control:
from django.http import JsonResponse

class CorsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        origin = request.headers.get('Origin')
        if origin in ['https://example.com']:
            response = self.get_response(request)
            response['Access-Control-Allow-Origin'] = origin
            
            response['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, PATCH, OPTIONS'
            response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
            response['Access-Control-Expose-Headers'] = 'X-RateLimit-Remaining, X-RateLimit-Reset'
            return response
        return self.get_response(request)
Flask
# Flask CORS Configuration

# Install: pip install flask-cors

from flask import Flask
from flask_cors import CORS, cross_origin

app = Flask(__name__)
CORS(app, resources={
    r"/api/*": {
        "origins": 'https://example.com',
        "methods": ["GET","POST","PUT","DELETE","PATCH","OPTIONS"],
        "allow_headers": ["Content-Type","Authorization"],
        "expose_headers": ["X-RateLimit-Remaining","X-RateLimit-Reset"],
        "supports_credentials": false,
        "max_age": 86400,
    }
})

# Or manual configuration:
@app.after_request
def add_cors_headers(response):
    origin = request.headers.get('Origin')
    if origin in ['https://example.com']:
        response.headers['Access-Control-Allow-Origin'] = origin
    
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, PATCH, OPTIONS'
    response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
    response.headers['Access-Control-Expose-Headers'] = 'X-RateLimit-Remaining, X-RateLimit-Reset'
    response.headers['Access-Control-Max-Age'] = '86400'
    return response
๐Ÿ’ก CORS Tips
  • Never use * for credentials requests
  • Preflight requests (OPTIONS) are cached with max-age
  • Test CORS with browser DevTools Network tab
  • For production, specify exact origins instead of wildcards

Setting Access-Control-Allow-Origin to a wildcard and also trying to allow credentialed requests at the same time looks like it should work but doesn't, browsers actually reject that specific combination outright, a well-known but easy-to-hit CORS gotcha that silently breaks an authenticated cross-origin request rather than throwing an obvious error explaining why. This tool generates a complete, consistent set of CORS headers, origin, methods, headers, and credentials together, avoiding invalid combinations like a wildcard origin paired with allowed credentials.

See more about the CORS Header Generator

Useful for generating CORS headers for an API that needs to allow credentialed requests without accidentally combining them with a wildcard origin, configuring exactly which methods and headers a cross-origin request is allowed to use, or debugging why a browser is silently blocking a cross-origin request despite headers that look correct at a glance.

Key features

  • Clean interface
  • Fast processing
  • No signup required
  • Works offline

Quick answers for CORS Header Generator

Which server frameworks can this generate config for?
Beyond raw HTTP headers, it outputs ready-to-paste CORS code for Nginx, Apache, Express.js, Next.js, Django, and Flask, matching each framework's actual header-setting syntax.
What do the preset scenarios configure?
Nine starting points, including Public API (fully open), With Credentials, Restricted origins, Dynamic Origin, and framework-specific presets for WordPress, Next.js, Express, Django, and Flask, each pre-filling realistic allowed methods, headers, and origins for that case.
Does this tool test my server's actual CORS behavior?
No, it only generates the header configuration for you to add to your own server, it does not send requests to check what your server currently returns.