HTTP Headers Reference
HTTP headers pass metadata with requests and responses. Understanding the most important ones is essential for building secure, performant APIs and web applications.
Common Request Headers
# Host: required in HTTP/1.1 - identifies the target server
Host: api.example.com
# Authorization: credentials for authentication
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIn0.sig
Authorization: Basic dXNlcjpwYXNzd29yZA== # Base64 user:password
Authorization: Digest username="alice", realm="api"
# Content-Type: format of the request body
Content-Type: application/json
Content-Type: application/x-www-form-urlencoded
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
Content-Type: text/plain; charset=utf-8
# Accept: formats the client can handle
Accept: application/json
Accept: text/html,application/xhtml+xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9,de;q=0.7
# Cache control in requests
Cache-Control: no-cache # Revalidate with server before using cache
Cache-Control: no-store # Do not cache at all
If-None-Match: "abc123" # Conditional GET by ETag
If-Modified-Since: Thu, 01 Jan 2025 00:00:00 GMT
# Origin & CORS
Origin: https://app.example.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: Authorization
# Cookies
Cookie: session_id=abc123; user_pref=dark
# User identification
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
Referer: https://app.example.com/dashboard # Note: historical misspelling
X-Forwarded-For: 203.0.113.42 # Client IP behind proxy/load balancer
X-Request-Id: 7f3a9b2c-1234-5678-abcd-def0CORS Response Headers
# CORS (Cross-Origin Resource Sharing) - allows browsers to make
# cross-origin requests. Set on the SERVER, enforced by BROWSERS.
# Allow specific origins (preferred over *)
Access-Control-Allow-Origin: https://app.example.com
# Allow all origins (only for public APIs)
Access-Control-Allow-Origin: *
# Allow credentials (cookies, auth headers) - cannot use * with this
Access-Control-Allow-Credentials: true
# Preflight response headers
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Request-Id
Access-Control-Max-Age: 86400 # Cache preflight result for 24 hours
# Expose custom headers to JavaScript
Access-Control-Expose-Headers: X-Total-Count, X-Request-Id
# CORS in Express.js
const cors = require('cors');
app.use(cors({
origin: ['https://app.example.com', 'https://admin.example.com'],
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400,
}));
# CORS in Next.js API route
export async function OPTIONS() {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': 'https://app.example.com',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}Security Headers
# HSTS - force HTTPS
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
# X-Frame-Options - prevent clickjacking (legacy, use CSP frame-ancestors instead)
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
# Content-Security-Policy - controls what resources can load
# (see Security Best Practices page for full details)
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com
# X-Content-Type-Options - prevent MIME sniffing
X-Content-Type-Options: nosniff
# Referrer-Policy - control Referer header
Referrer-Policy: strict-origin-when-cross-origin
Referrer-Policy: no-referrer # Never send Referer
Referrer-Policy: same-origin # Only for same-origin requests
# Permissions-Policy (formerly Feature-Policy)
Permissions-Policy: camera=(), microphone=(), geolocation=(self)
# Cross-Origin headers
Cross-Origin-Opener-Policy: same-origin # Isolate browsing context
Cross-Origin-Embedder-Policy: require-corp # Required for SharedArrayBuffer
Cross-Origin-Resource-Policy: same-site
# Set-Cookie security flags
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600
# HttpOnly - not accessible via JS (XSS protection)
# Secure - only sent over HTTPS
# SameSite - CSRF protection (Strict|Lax|None)
# Max-Age - expiry in seconds; or Expires=dateCaching Headers
# Cache-Control directives (response)
Cache-Control: public, max-age=86400 # Cache 1 day, CDN + browser
Cache-Control: private, max-age=3600 # Browser only (not CDN)
Cache-Control: no-cache # Must revalidate before use
Cache-Control: no-store # Never cache (bank data)
Cache-Control: immutable # Never revalidate (content-hashed files)
Cache-Control: stale-while-revalidate=60 # Serve stale, refresh in background
Cache-Control: s-maxage=3600 # CDN max-age (overrides max-age for shared caches)
# Revalidation
ETag: "33a64df551425fcc55e4d42a148795d9" # Fingerprint of resource
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
# Conditional GET (saves bandwidth - 304 = no body)
# Client sends:
If-None-Match: "33a64df551425fcc55e4d42a148795d9"
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT
# Server responds 304 Not Modified if unchanged
# Vary: tells caches that response varies by request header
Vary: Accept-Encoding # Cache separate gzip and identity versions
Vary: Accept # Cache separate JSON and HTML versions
Vary: Origin # Cache per Origin (CORS)
# Caching strategy per file type:
# HTML: Cache-Control: no-cache (always revalidate)
# CSS/JS (hashed): Cache-Control: public, max-age=31536000, immutable
# API responses: Cache-Control: private, no-cache
# Public assets (CDN): Cache-Control: public, s-maxage=86400, max-age=3600Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free