Headers carry metadata about a request or response — auth, caching, content negotiation, and security policy. This sheet groups the ones you'll actually reach for, separate from the hundreds that exist but rarely matter.
Quick reference
Common request headers
| Header |
Purpose |
Example |
| `Authorization` |
Credentials |
`Bearer eyJhbGciOi...` |
| `Content-Type` |
Body's media type |
`application/json` |
| `Accept` |
Media types the client can handle |
`application/json, text/html;q=0.9` |
| `User-Agent` |
Client identification string |
`Mozilla/5.0 (...)` |
| `Origin` |
Origin the request came from (CORS) |
`https://example.com` |
| `If-None-Match` / `If-Modified-Since` |
Conditional GET for caching |
`"33a64df5"` |
| `X-Requested-With` |
Legacy AJAX marker (mostly obsolete) |
`XMLHttpRequest` |
| `Idempotency-Key` |
Client-supplied key so a retried mutation isn't double-applied |
opaque string |
Common response headers
| Header |
Purpose |
Example |
| `Content-Type` |
Body's media type |
`application/json; charset=utf-8` |
| `Cache-Control` |
Caching directives |
`public, max-age=3600` |
| `ETag` |
Content fingerprint for conditional requests |
`"33a64df5"` |
| `Location` |
Redirect target / created resource URL |
`/orders/42` |
| `Set-Cookie` |
Sets a cookie |
`session=abc; HttpOnly; Secure; SameSite=Strict` |
| `Retry-After` |
Seconds (or date) to wait before retrying |
`30` |
| `Vary` |
Which request headers affect caching |
`Accept-Encoding, Origin` |
Security response headers
| Header |
Purpose |
| `Content-Security-Policy` |
Whitelist allowed script/style/image/connect sources, mitigates XSS |
| `X-Content-Type-Options: nosniff` |
Stops browsers guessing MIME types (blocks some MIME-confusion attacks) |
| `X-Frame-Options: DENY` |
Blocks the page from being framed (clickjacking defense — superseded by CSP `frame-ancestors` but still widely sent for older browsers) |
| `Strict-Transport-Security` |
Forces HTTPS for future visits (`max-age=31536000; includeSubDomains`) |
| `Referrer-Policy` |
Controls how much of the referring URL is leaked on navigation |
| `Permissions-Policy` |
Disables browser features per-origin (camera, geolocation, etc.) |
| `Cross-Origin-Resource-Policy` |
Restricts which origins can load this resource |
| `Cross-Origin-Opener-Policy` |
Isolates the browsing context from cross-origin popups |
Common patterns
Bearer token auth
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
CORS preflight response
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PATCH
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 600
Access-Control-Allow-Origin: cannot be combined with a request sent in credentialed mode (fetch(url, {credentials: 'include'}), xhr.withCredentials = true — i.e. cookies, HTTP auth dialogs, or TLS client certs) — browsers reject that combination outright. A manually attached Authorization: Bearer ... header is not "credentials mode" by itself; plenty of production bearer-token APIs serve Access-Control-Allow-Origin: with no issue.
A reasonable security header baseline
Content-Security-Policy: default-src 'self'; frame-ancestors 'none'
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
Strict-Transport-Security: max-age=31536000; includeSubDomains
Rate-limit response headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1735689600
Retry-After: 30
Pitfalls
Authorization gets stripped by some proxies/CDNs by default: if a bearer token mysteriously never reaches your backend, check whether the reverse proxy or .htaccess config forwards it — Apache in particular drops it unless you explicitly rewrite HTTP_AUTHORIZATION back in.
Cache-Control: no-cache doesn't mean "don't cache": it means "cache it, but revalidate with the server before using it." For "never cache this," use no-store.
- Header names are case-insensitive, but values often aren't:
content-type: APPLICATION/JSON is the same header as Content-Type: application/json, but a Content-Type value comparison in application code is usually case-sensitive for the subtype.
- Setting
X-Frame-Options and a conflicting CSP frame-ancestors value: modern browsers honor frame-ancestors and ignore X-Frame-Options when both are present but disagree — always keep them consistent, and know that CSP wins.
- *
Vary: ** technically means the response is effectively uncacheable by any shared cache — a header some CDNs add automatically and then get confused about why nothing caches.
Related ZipKit tools
- CSP Header Builder — generate a correct
Content-Security-Policy value without hand-writing the directive syntax.
- JWT Decoder — inspect what's actually inside the token you're sending in
Authorization: Bearer.
- Nginx Reverse Proxy Generator — generate the
proxy_set_header config these headers need to survive a reverse proxy hop.
Related cheatsheets
- HTTP Status Codes — the status line these headers accompany on every response.
- .htaccess Cheatsheet — the Apache directives that actually set these headers on shared hosting.