HTTP 协议详解教程 / 第 6 章:HTTP 头部字段
第 6 章:HTTP 头部字段
头部字段是 HTTP 消息的元数据,控制着缓存、认证、内容协商、安全策略等核心机制。掌握头部字段是精通 HTTP 的必经之路。
6.1 头部字段基础
语法
Header-Name: Header-Value
- 字段名:不区分大小写
- 字段值:可能区分大小写
- 可以有多值:用逗号分隔
Cache-Control: max-age=3600, public
分类
| 类型 | 说明 | 示例 |
|---|---|---|
| 通用头(General) | 请求和响应都可用 | Cache-Control, Connection, Date |
| 请求头(Request) | 仅请求中使用 | Host, Accept, Authorization |
| 响应头(Response) | 仅响应中使用 | Server, Set-Cookie, ETag |
| 表示头(Representation) | 描述消息体 | Content-Type, Content-Length |
6.2 请求头详解
主机与连接
Host: api.example.com:8080
Connection: keep-alive
| 头部 | 说明 | 示例 |
|---|---|---|
| Host | 目标主机(HTTP/1.1 必须) | Host: example.com |
| Connection | 连接管理 | keep-alive / close / Upgrade |
| Keep-Alive | 持久连接参数 | timeout=5, max=100 |
内容协商
Accept: application/json, text/html;q=0.9
Accept-Language: zh-CN, en-US;q=0.8
Accept-Encoding: gzip, br, deflate
Accept-Charset: utf-8
import requests
headers = {
'Accept': 'application/json',
'Accept-Language': 'zh-CN,en;q=0.9',
'Accept-Encoding': 'gzip, br'
}
response = requests.get('https://api.example.com/data', headers=headers)
print(response.headers['Content-Type'])
认证与凭据
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Cookie: session=abc123; user=alice
Proxy-Authorization: Basic dXNlcjpwYXNz
条件请求
If-None-Match: "etag-value"
If-Modified-Since: Wed, 10 May 2026 10:00:00 GMT
If-Match: "etag-value"
If-Unmodified-Since: Wed, 10 May 2026 10:00:00 GMT
If-Range: "etag-value"
Range: bytes=0-1023
请求上下文
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Referer: https://example.com/previous-page
Origin: https://frontend.example.com
DNT: 1
X-Request-ID: 550e8400-e29b-41d4
6.3 响应头详解
内容相关
Content-Type: application/json; charset=utf-8
Content-Length: 256
Content-Encoding: gzip
Content-Language: zh-CN
Content-Disposition: attachment; filename="report.pdf"
Content-Range: bytes 0-1023/10240
缓存控制
Cache-Control: max-age=3600, public
ETag: "abc123"
Last-Modified: Wed, 10 May 2026 10:00:00 GMT
Expires: Thu, 11 May 2026 10:00:00 GMT
Vary: Accept, Accept-Encoding
安全策略
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
CORS
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400
Access-Control-Expose-Headers: X-Total-Count
Cookie
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600
Set-Cookie: theme=dark; Path=/; Max-Age=31536000
6.4 Content-Type 详解
Content-Type 是最重要的头部之一,指示消息体的媒体类型。
语法
Content-Type: type/subtype[; parameter=value]
常见类型
| 类型 | 说明 | 示例场景 |
|---|---|---|
text/html | HTML 文档 | 网页 |
text/plain | 纯文本 | 日志、调试 |
application/json | JSON | REST API |
application/xml | XML | SOAP API |
application/x-www-form-urlencoded | 表单 | HTML 表单 |
multipart/form-data | 多部分 | 文件上传 |
application/octet-stream | 二进制流 | 文件下载 |
application/pdf | PDF 文档 | 文档下载 |
image/jpeg | JPEG 图片 | 图片资源 |
image/png | PNG 图片 | 图片资源 |
application/javascript | JavaScript | 脚本文件 |
text/css | CSS 样式 | 样式文件 |
application/wasm | WebAssembly | WASM 模块 |
multipart/form-data 结构
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="username"
alice
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="avatar"; filename="photo.jpg"
Content-Type: image/jpeg
<binary image data>
------WebKitFormBoundary7MA4YWxkTrZu0gW--
import requests
# 文件上传
with open('photo.jpg', 'rb') as f:
response = requests.post(
'https://api.example.com/upload',
files={
'avatar': ('photo.jpg', f, 'image/jpeg'),
},
data={
'username': 'alice'
}
)
6.5 Cache-Control 详解
Cache-Control 控制缓存行为,是最复杂的头部之一。
指令列表
| 指令 | 类型 | 说明 |
|---|---|---|
max-age=N | 请求+响应 | 缓存有效时间(秒) |
s-maxage=N | 响应 | 共享缓存有效时间(覆盖 max-age) |
no-cache | 请求+响应 | 可缓存但每次需验证 |
no-store | 请求+响应 | 不缓存任何内容 |
public | 响应 | 任何缓存都可存储 |
private | 响应 | 仅浏览器可缓存 |
must-revalidate | 响应 | 过期后必须验证 |
proxy-revalidate | 响应 | 代理必须验证 |
immutable | 响应 | 内容不会改变 |
stale-while-revalidate=N | 响应 | 过期后可在后台验证 |
no-transform | 请求+响应 | 不允许代理转换内容 |
常见缓存策略
# 静态资源(长期缓存,使用 hash 文件名)
Cache-Control: public, max-age=31536000, immutable
# API 响应(不缓存)
Cache-Control: no-store
# HTML 页面(协商缓存)
Cache-Control: no-cache
# 用户数据(仅浏览器缓存)
Cache-Control: private, max-age=300
# CDN + 浏览器缓存
Cache-Control: public, s-maxage=86400, max-age=3600
# Nginx 缓存配置
# 静态资源
location ~* \.(css|js|png|jpg|ico|woff2)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
# HTML
location / {
add_header Cache-Control "no-cache";
}
# API
location /api/ {
add_header Cache-Control "no-store";
}
6.6 自定义头部
命名规范
| 前缀 | 说明 | 示例 |
|---|---|---|
X- | 非标准(已废弃,但仍广泛使用) | X-Request-ID |
| 无前缀 | IANA 注册 | Authorization |
Sec- | 安全相关(浏览器自动添加) | Sec-Fetch-Mode |
常用自定义头部
# 请求追踪
X-Request-ID: 550e8400-e29b-41d4
X-Correlation-ID: abc-123
# API 版本
X-API-Version: v2
# 限流信息(响应头)
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 1715328000
# 分页信息(响应头)
X-Total-Count: 1500
X-Page-Count: 75
# 客户端信息
X-Forwarded-For: 203.0.113.1
X-Forwarded-Proto: https
X-Real-IP: 203.0.113.1
// Express.js 中间件:添加请求 ID
const { v4: uuidv4 } = require('uuid');
app.use((req, res, next) => {
const requestId = req.headers['x-request-id'] || uuidv4();
req.requestId = requestId;
res.setHeader('X-Request-ID', requestId);
next();
});
6.7 响应头 Vary
Vary 告诉缓存服务器哪些请求头影响响应内容。
# 响应根据 Accept-Encoding 不同而不同
Vary: Accept-Encoding
# 根据 Accept 和 Authorization 不同
Vary: Accept, Authorization
# Nginx Vary 配置
gzip_vary on; # 添加 Vary: Accept-Encoding
📝 注意:Vary 设为
*会导致缓存基本失效。
6.8 业务场景:完整请求头示例
浏览器 API 请求
GET /api/users?page=1 HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Accept-Encoding: gzip, deflate, br
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Origin: https://app.example.com
Referer: https://app.example.com/users
Connection: keep-alive
Cache-Control: no-cache
X-Request-ID: abc-123-def-456
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
服务器响应
HTTP/1.1 200 OK
Date: Wed, 10 May 2026 10:00:00 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 256
Content-Encoding: br
Cache-Control: private, max-age=0, must-revalidate
ETag: "user-list-v5"
Vary: Accept, Accept-Encoding
X-Request-ID: abc-123-def-456
X-Total-Count: 150
X-Page-Count: 8
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Expose-Headers: X-Total-Count, X-Page-Count
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
⚠️ 注意事项
- Host 头必须:HTTP/1.1 强制要求,缺少会导致 400 错误
- 大小写不敏感:头部名不区分大小写,但值可能区分
- 重复头部:部分头部可以重复(Set-Cookie),大部分会被合并
- 代理影响:代理可能添加/修改头部(X-Forwarded-For 等)
- 自定义头部命名:IETF 已废弃
X-前缀,但实际中仍广泛使用 - 不要依赖 User-Agent:可被伪造,不应作为安全决策依据
🔗 扩展阅读
下一章:第 7 章:Cookie 机制 — Set-Cookie、属性详解、安全策略、Session 管理