正在加载,请稍候…

HTTP Headers Explained: Request, Response, and Security Headers

A practical guide to HTTP headers — covering request headers, response headers, CORS, caching, security headers like CSP and HSTS, and how to set them correctly.

HTTP Headers: The Complete Developer Reference

HTTP headers are key-value pairs sent with every request and response. They control caching, authentication, content negotiation, security policies, and much more. Understanding them is essential for debugging APIs, fixing CORS issues, and hardening web applications.

Request Headers

These headers are sent by the client (browser or HTTP client) to the server.

Identity and Content

Header Purpose Example
Host Target hostname (required in HTTP/1.1) Host: api.example.com
User-Agent Client software identifier User-Agent: Mozilla/5.0...Chrome/124
Accept Media types the client can handle Accept: application/json, text/html
Accept-Language Preferred response language Accept-Language: en-US,en;q=0.9
Accept-Encoding Compression the client supports Accept-Encoding: gzip, deflate, br
Content-Type Body format for POST/PUT Content-Type: application/json
Content-Length Body size in bytes Content-Length: 348

Authentication

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Basic dXNlcjpwYXNzd29yZA==
Authorization: Digest username="bob", realm="api"...

The Authorization header transmits credentials. Bearer tokens (JWT) are most common in APIs. Basic is base64-encoded user:password — only safe over HTTPS.

Caching Control (Request Side)

Cache-Control: no-cache        # Revalidate even if cached
Cache-Control: no-store        # Never cache
Cache-Control: max-age=0       # Consider cached copy stale
If-None-Match: "abc123"        # Conditional GET by ETag
If-Modified-Since: Tue, 15 Nov 2022 12:45:26 GMT

CORS Preflight

Origin: https://app.example.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: Content-Type, Authorization

Browsers send a preflight OPTIONS request with these headers before cross-origin requests that use methods other than GET/POST or include custom headers.

Response Headers

Content Delivery

Header Purpose Example
Content-Type Response body format + charset Content-Type: application/json; charset=utf-8
Content-Length Body size Content-Length: 1024
Content-Encoding Applied compression Content-Encoding: gzip
Transfer-Encoding Chunked for streaming Transfer-Encoding: chunked
Location Redirect target URL Location: https://example.com/new-path

Caching

# Public resources (CSS, images): cache 1 year, revalidate on change
Cache-Control: public, max-age=31536000, immutable

# API responses: no caching
Cache-Control: no-store

# HTML pages: revalidate each request
Cache-Control: no-cache

# ETag for conditional requests
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

# Last modification date
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

# Shared cache expiry (legacy, prefer Cache-Control)
Expires: Thu, 01 Dec 2034 16:00:00 GMT

Cache-Control directive cheat sheet:

Directive Meaning
public Any cache (CDN, browser) may store
private Browser only, not CDN
no-cache Must revalidate before using cached copy
no-store Never store anywhere
max-age=N Fresh for N seconds
s-maxage=N CDN max-age (overrides max-age for shared caches)
immutable Content won't change; skip revalidation
stale-while-revalidate=N Serve stale while fetching fresh in background

CORS Headers

Cross-Origin Resource Sharing controls which external origins can access a resource.

Server Response Headers

# Allow specific origin
Access-Control-Allow-Origin: https://app.example.com

# Allow any origin (unsafe for authenticated endpoints)
Access-Control-Allow-Origin: *

# Response to preflight: allowed methods
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH

# Response to preflight: allowed custom headers
Access-Control-Allow-Headers: Content-Type, Authorization, X-Request-ID

# How long to cache preflight result (seconds)
Access-Control-Max-Age: 86400

# Allow credentials (cookies, auth headers)
Access-Control-Allow-Credentials: true

# Which headers the browser can expose to JS
Access-Control-Expose-Headers: X-Total-Count, X-Page

Critical rule: You cannot use Access-Control-Allow-Origin: * together with Access-Control-Allow-Credentials: true. Credentialed requests require a specific origin.

CORS Error Flowchart

  1. Browser makes cross-origin request → browser adds Origin header
  2. If request is "simple" (GET/POST + standard headers) → request goes through, browser checks response Access-Control-Allow-Origin
  3. If request is "complex" (DELETE, PUT, or custom headers) → browser sends OPTIONS preflight first
  4. If preflight fails → original request is blocked, CORS error in console

Security Headers

These headers are your first line of defense against XSS, clickjacking, and injection attacks.

Content-Security-Policy (CSP)

CSP tells the browser which sources are allowed to load scripts, styles, images, and other resources.

# Strict CSP for SPAs
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.example.com; frame-ancestors 'none'

# Report violations without enforcing (testing phase)
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Common CSP directives:

Directive Controls
default-src Fallback for all resource types
script-src JavaScript sources
style-src CSS sources
img-src Image sources
connect-src XHR, fetch, WebSocket targets
frame-ancestors Who can embed this page in iframe
object-src Flash/plugins (set to 'none')

Strict-Transport-Security (HSTS)

Forces HTTPS for all future visits:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • max-age: Seconds to remember HTTPS requirement
  • includeSubDomains: Apply to all subdomains
  • preload: Include in browser's built-in HSTS list (submit at hstspreload.org)

Other Security Headers

# Block MIME sniffing (e.g., loading script disguised as image)
X-Content-Type-Options: nosniff

# Prevent clickjacking (legacy, prefer frame-ancestors CSP)
X-Frame-Options: DENY

# Enable browser XSS filter (legacy, modern browsers ignore)
X-XSS-Protection: 1; mode=block

# Control referrer information
Referrer-Policy: strict-origin-when-cross-origin

# Restrict browser features (camera, microphone, geolocation)
Permissions-Policy: camera=(), microphone=(), geolocation=(self)

Recommended Security Header Stack (2026)

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none'
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: interest-cohort=()

Test your headers at securityheaders.com.

Custom Headers Convention

By convention, custom headers use the X- prefix (though this was deprecated in RFC 6648):

X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1699012800
X-Correlation-ID: abc-123

Rate limit headers are increasingly standardized as RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset (without X-).

Debugging Headers

# View request + response headers
curl -v https://api.example.com/users

# View response headers only
curl -I https://example.com

# Send custom headers
curl -H "Authorization: Bearer TOKEN" -H "Accept: application/json" https://api.example.com

# Follow redirects, show final headers
curl -L -D - https://example.com -o /dev/null

In Chrome DevTools → Network tab → click any request → Headers panel shows both request and response headers, with values decoded.

→ Decode JWT tokens in your browser with the JWT Parser. Check HTTP status codes at HTTP Status Codes.