HTTP Headers
Headers are the metadata that accompanies every request and response — content type, length, caching rules, authentication, cookies, CORS permissions, and more. They're key–value pairs sent before the body. Getting headers right is what makes content render correctly, caches behave, and security protections engage. This page covers reading them, setting them, and the ones that matter most.
Reading request headers
createServer((req, res) => {
// Node lowercases all incoming header names:
const contentType = req.headers['content-type']
const accept = req.headers['accept']
const auth = req.headers['authorization']
const host = req.headers['host']
res.end('ok')
}).listen(3000)Setting response headers
// One at a time:
res.setHeader('Content-Type', 'application/json')
res.setHeader('Cache-Control', 'no-store')
// Read/remove before sending:
res.getHeader('Content-Type') // 'application/json'
res.removeHeader('X-Powered-By')
// Or all at once with the status:
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8',
'Cache-Control': 'public, max-age=3600',
})The essential headers
Header | Direction | Purpose |
|---|---|---|
| Both | Media type of the body (+ charset) |
| Both | Body size in bytes |
| Request | Media types the client wants |
| Request | Credentials (Bearer token, Basic) |
| Both | Caching rules |
| Resp / Req | Cookies out / in |
| Response | Target for redirects / created resource |
| Response | Compression (gzip, br) |
| Response | Validators for conditional requests |
Content-Type and charset
Content | Content-Type |
|---|---|
HTML |
|
JSON |
|
Plain text |
|
Form (urlencoded) |
|
File upload / multipart |
|
Binary download |
|
Caching headers
// Cache a static asset for a day, allow shared caches:
res.setHeader('Cache-Control', 'public, max-age=86400')
// Never cache (sensitive/personalized):
res.setHeader('Cache-Control', 'no-store')
// Validators enable cheap 304 responses:
res.setHeader('ETag', '"abc123"')
res.setHeader('Last-Modified', new Date(mtime).toUTCString())CORS headers
Browsers block cross-origin requests by default. To allow them, the server sends Access-Control-Allow-* headers — and must answer the OPTIONS preflight:
function setCors(res) {
res.setHeader('Access-Control-Allow-Origin', 'https://app.example.com')
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
}
createServer((req, res) => {
setCors(res)
if (req.method === 'OPTIONS') { // preflight
res.writeHead(204).end()
return
}
res.end('data')
}).listen(3000)Security headers
Header | Protects against |
|---|---|
| Forces HTTPS (downgrade attacks) |
| MIME-type sniffing |
| XSS / injection |
| Clickjacking |
| Leaking URLs to other sites |
Cookies
// Set a secure, HTTP-only session cookie:
res.setHeader('Set-Cookie',
'sessionId=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=3600; Path=/')
// Multiple cookies → pass an array:
res.setHeader('Set-Cookie', ['a=1; Path=/', 'b=2; Path=/'])