How HTTP Headers Work — A Developer Guide
HTTP headers are key-value pairs sent with every HTTP request and response. Request headers tell the server about the client (browser type, accepted formats, authentication). Response headers tell the browser how to handle the response (cache it, block iframes, restrict resource loading). You set them in your server config or application code.
Every HTTP request and response includes a set of headers. They are invisible to users but control almost everything: caching, security, CORS, content type, authentication, and compression. Understanding headers is the foundation of backend web development.
Request headers — browser to server
When a browser makes a request, it sends headers describing what it wants and who it is:
GET /api/data HTTP/2 Host: api.example.com Accept: application/json Accept-Encoding: gzip, deflate, br Authorization: Bearer eyJhbGciOiJIUzI1NiJ9... Origin: https://app.example.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...
Response headers — server to browser
The server responds with headers telling the browser what to do with the response:
HTTP/2 200 Content-Type: application/json Content-Encoding: gzip Cache-Control: public, max-age=60 Access-Control-Allow-Origin: https://app.example.com Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff
The most important headers to know
| Header | Direction | What it does |
|---|---|---|
Cache-Control | Response | How long to cache the response |
Content-Type | Both | Format of the body (JSON, HTML, image) |
Authorization | Request | Authentication credentials |
Origin | Request | Where the request originated (CORS) |
Access-Control-Allow-Origin | Response | Which origins can read the response (CORS) |
Strict-Transport-Security | Response | Force HTTPS for future requests |
Content-Security-Policy | Response | Which resources the page can load |
Set-Cookie | Response | Set a cookie in the browser |
How to set response headers
# Nginx
add_header Cache-Control "public, max-age=3600" always;
add_header X-Content-Type-Options "nosniff" always;
# Express (Node.js)
res.set('Cache-Control', 'public, max-age=3600');
res.set('X-Content-Type-Options', 'nosniff');
# FastAPI (Python)
from fastapi import Response
response.headers["Cache-Control"] = "public, max-age=3600"
# Vercel (vercel.json)
{ "headers": [{ "source": "/(.*)", "headers": [
{ "key": "Cache-Control", "value": "public, max-age=3600" }
]}]}
How CDNs modify headers
CDNs sit between users and your server. They can add, remove, or modify headers:
- Cloudflare adds
cf-ray,cf-cache-status - Vercel adds
x-vercel-id,x-vercel-cache - CDNs read
Cache-Controlto decide what to cache - Cloudflare strips
Set-Cookiefrom cached responses
How to inspect headers in your browser
1. Open DevTools (F12) 2. Click Network tab 3. Click any request 4. Click Headers tab 5. See Request Headers and Response Headers
# Or with curl: curl -sI https://example.com | head -20