HTTP 头部对照表
HTTP 头部(Header)是请求与响应中携带的键值对元数据。本表列出开发中最高频的请求头与响应头,含类型与中文说明,调试接口时快速查阅。
原理解析
HTTP 头部是请求/响应里的键值对,承载认证、缓存、内容协商、安全等元信息,与正文彼此独立。请求头(User-Agent、Authorization、Accept)描述「调用方想要什么」,响应头(Content-Type、Set-Cookie、Cache-Control)描述「服务端返回了什么」。
安全相关头部尤为关键:CSP 限制可加载资源防 XSS,HSTS 强制 HTTPS,CORS 头部控制跨域访问。合理配置头部能在不改动业务代码的前提下显著提升安全性。
什么时候该查这张表
这张表在你要查某个 HTTP 请求头的准确语义时有用。它覆盖内容协商、缓存控制、语言协商、认证、CORS、安全加固等常用头,给出类型与含义。写接口调试或读框架文档时查它。
不该查的情况:你在调 CDN 与反向代理的具体行为。头在传输链路上可能被改写、重排或剥离,Nginx 与 CDN 的处理往往和标准不一致,这类问题需要看实际响应而非头字段列表。
判断标准:先看这个头是请求头还是响应头 —— 同名头在两侧含义完全不同(Content-Type 在请求里描述 body,在响应里描述 body;而 Accept 只在请求里出现)。分清方向就不会张冠李戴。
特别注意 CORS 相关头的联动:Access-Control-Allow-Origin 等只在响应里,且预检请求的通过标准比实际请求严格。很多「跨域 POST 失败但 GET 正常」就是预检没通过。
边界与常见陷阱
CORS 预检失败是「跨域 POST 不通但 GET 通」的主因
带自定义头、非简单方法或非简单 Content-Type 的跨域请求会先发 OPTIONS 预检。预检要求服务端同时返回 Access-Control-Allow-Methods、Access-Control-Allow-Headers 与 Access-Control-Allow-Origin,任一缺失浏览器就拒绝,且错误只体现在浏览器控制台,服务端日志里一切正常。调试要点:先用 curl 手动发 OPTIONS 看响应头,再确认 Allow-Headers 覆盖了实际用到的自定义头。
Cache-Control 头写错会让更新不生效或隐私泄露
两个方向都会出事:静态资源缺 max-age 或版本号 ⇒ 用户拿到旧版本排查半天;而带用户数据的响应误加 public, max-age=3600 ⇒ 缓存被 CDN 共享,同一份内容发给不同用户。后者是安全事故而非体验问题。规则:内容哈希文件名配 immutable 长缓存;HTML 配 no-cache 强制校验;任何含用户数据的响应必须 private 或 no-store。
Accept-Encoding 与压缩协商的坑在同源实现不一致
正确流程是客户端用 Accept-Encoding 声明支持(gzip, br),服务端选一种并在 Content-Encoding 回应。常见问题:① 服务端无条件 gzip,不看 Accept-Encoding,导致不支持的客户端拿到压缩数据;② 同时声明并返回 gzip 与 br,客户端无法判断;③ 压缩了本已压缩的图片/视频,CPU 白耗且体积不降。规范做法是按协商结果设置 Vary: Accept-Encoding,否则缓存会把压缩版喂给不支持的客户端。
与相邻内容的分工
要查状态码语义(502 与 504 的区别),用站内「HTTP 状态码」页;本页只讲请求头字段。
要查方法语义(幂等性、请求体规则),用站内「HTTP 方法」页,与本页配套但关注点不同。
要理解 HTTP/2 与 HTTP/3 的头部压缩与连接复用差异,属协议实现层面,本表不覆盖。
若目的是排查某个响应在浏览器里表现异常,先看实际响应头(Network 面板),不要凭头字段列表推断——代理层可能改写。
实战片段
要点:① 跨域 POST/自定义头报错的根因多在预检未通过,调试第一动作是用 curl 手发 OPTIONS 查三个 Allow 头,且要确认 Allow-Headers 覆盖了实际用到的自定义头;② 静态资源用内容哈希文件名配 immutable 长缓存,HTML 用 no-cache 强制校验而非 no-store;③ 任何含用户数据的响应必须 private 或 no-store,加错成 public 是安全事故;④ 压缩必须按 Accept-Encoding 协商并带 Vary 头,否则缓存会把压缩版喂给不支持的客户端。
# ① 手动发预检,验证 CORS(最实用的调试动作)
curl -i -X OPTIONS 'https://api.example.com/orders' -H 'Origin: https://app.example.com' -H 'Access-Control-Request-Method: POST' -H 'Access-Control-Request-Headers: content-type,x-request-id'
# 必须同时看到:Access-Control-Allow-Origin / -Methods / -Headers
# 缺任一项 ⇒ 浏览器直接拒绝,且服务端日志看不到异常
# ② 查看实际响应头
curl -sSI https://example.com/ | grep -iE 'cache-control|vary|etag|content-encoding'
# Age: 120 ⇒ 命中了缓存(解释「改了却没生效」)
# ③ 压缩协商:客户端声明,服务端选一种
curl -sSI -H 'Accept-Encoding: gzip, br' https://example.com/a.json | grep -i 'content-encoding' # 回 gzip 或 br,**不能两个都返回**
# ⚠️ 服务端必须带 Vary: Accept-Encoding,否则缓存串味
# ④ 内容哈希 + immutable(静态资源)
# app.9f2c1a.js + Cache-Control: public, max-age=31536000, immutable
# 5 HTML 用 no-cache 强制校验(而不是 no-store 浪费带宽)
curl -sSI https://example.com/ | grep -i cache-control
# Cache-Control: no-cache ← 每次带 If-None-Match 校验
curl -sS -H 'If-None-Match: "abc"' https://example.com/ -o /dev/null -w '%{http_code}
'
# 304 = 未变化(省带宽) 200 = 变了
# 6 含用户数据的响应必须 private(绝不能 public)
curl -sSI https://example.com/api/me | grep -i cache-control
# Cache-Control: private, no-store ← 绝不能让 CDN 共享实践注解
- Set-Cookie 只能追加,多个 cookie 不能合并成一行它是少数「可重复但不可合并」的头部:写成一行用逗号分隔会被浏览器当作一个畸形 cookie。正确做法是每个 cookie 一条 Set-Cookie 响应头。
- Content-Length 与 Transfer-Encoding 同时出现是协议错误两者并存会让接收方无法判断消息边界(存在请求走私风险)。若用了分块传输就不要带 Content-Length;网关通常会在这种请求上直接返回 400。
- Vary 漏项是「缓存串数据」的常见根因若响应随 Accept-Language、Origin 等请求头变化,却未在 Vary 中声明,CDN 与浏览器可能把 A 语言的响应喂给 B 语言用户。返回本地化或多态内容时,务必补齐 Vary。
数据来源
- RFC 9110 (semantics)
- RFC 9111 (caching)
- RFC 6265 (cookies)
- IANA Message Headers Registry
上述编号、名称与定义均来自公开规范,本站不主张对规范数据本身的独创性;本页的编排方式、中文释义与实践注解由本站撰写。
| 头部 | 类型 | 说明 |
|---|---|---|
| Accept | 请求 | 客户端可处理的媒体类型(如 application/json, text/html) |
| Accept-Encoding | 请求 | 可接受的压缩编码(gzip、br、deflate) |
| Accept-Language | 请求 | 可接受的自然语言与权重(如 zh-CN,en;q=0.8) |
| Authorization | 请求 | 认证凭证,如 Bearer <token> 或 Basic <base64> |
| Cache-Control | 通用 | 缓存指令(no-cache、max-age=3600、private) |
| Cookie | 请求 | 发送服务端之前通过 Set-Cookie 下发的 cookie |
| Content-Type | 通用 | 请求体或响应体的媒体类型(如 application/json; charset=utf-8) |
| Host | 请求 | 目标主机名与端口,HTTP/1.1 必需 |
| Origin | 请求 | 跨域请求的来源域,用于 CORS 校验 |
| Referer | 请求 | 发起请求的页面 URL(历史拼写保留为 Referer) |
| User-Agent | 请求 | 客户端软件标识(浏览器 / 爬虫 / 库名称与版本) |
| If-None-Match | 请求 | 条件请求,携带上次 ETag 做缓存校验 |
| If-Modified-Since | 请求 | 条件请求,仅当资源在此时间后修改才返回 |
| Access-Control-Allow-Origin | 响应 | CORS 允许的来源(* 或具体域) |
| Content-Length | 响应 | 响应体的字节长度 |
| Content-Encoding | 响应 | 响应体应用的压缩编码(gzip、br) |
| Set-Cookie | 响应 | 服务端下发 cookie,可带 HttpOnly/Secure/SameSite |
| ETag | 响应 | 资源的版本标识,用于条件请求缓存校验 |
| Last-Modified | 响应 | 资源最后修改时间 |
| Location | 响应 | 3xx 重定向的目标 URL |
| Expires | 响应 | 响应过期的绝对时间(已被 Cache-Control 取代) |
| Server | 响应 | 服务器软件名称与版本 |
| WWW-Authenticate | 响应 | 401 时返回的认证挑战方式(如 Basic) |
| Retry-After | 响应 | 503/429 时建议的重试等待秒数 |
| Strict-Transport-Security | 响应 | HSTS,强制后续请求使用 HTTPS |
| Connection | 通用 | 连接管理(keep-alive 或 close) |
| Date | 通用 | 消息生成的日期时间(GMT) |
常见问题
请求头和响应头有什么区别?
请求头由客户端发送,携带 Accept、Authorization、Cookie 等告诉服务器"我想要什么、我是谁";响应头由服务器返回,携带 Content-Type、Set-Cookie、Cache-Control 等,告诉客户端"我给了什么、怎么处理"。部分头部(如 Content-Type、Cache-Control)在两边都能出现。
Cache-Control 常用指令有哪些?
常见有 no-store(不缓存)、no-cache(需校验)、max-age=秒(最大存活)、public/private(是否可被代理缓存)、must-revalidate(过期必须回源校验)。
CORS 相关的头部有哪些?
请求侧常用 Origin;响应侧常用 Access-Control-Allow-Origin(允许来源)、Access-Control-Allow-Methods(允许方法)、Access-Control-Allow-Headers(允许头部)、Access-Control-Allow-Credentials(是否带凭证)。
ETag 和 Last-Modified 如何配合缓存?
二者都是验证器。客户端首次请求得到 ETag/Last-Modified,后续请求通过 If-None-Match/If-Modified-Since 做条件请求;若资源未变化,服务器返回 304 Not Modified,客户端直接用缓存,节省带宽。