| 请求头名称 | 分类 | 说明 | 示例值 |
|---|
Name: value,
也支持浏览器开发者工具「Copy as cURL」的整段内容(会自动提取其中的 -H 参数)。
已收录的请求头会同时显示分类与说明。
HTTP 请求头是客户端发给服务器的「附加说明书」——它不改变请求的目标,却决定了服务器如何理解这个请求:接受什么格式、用什么身份、能不能走缓存、来自哪个 IP、经过哪条链路。这个工具收录了 168 个常用请求头,按 17 个分类整理,并附带一个请求头原文解析器。
Accept、缓存、X-Forwarded、追踪),列表实时筛选;Name: value),自动逐条解析并标注是否已收录;-H 参数。| 分类 | 内容举例 | 数量 |
|---|---|---|
| 内容协商 | Accept、Accept-Encoding | 7 |
| 内容主体 | Content-Type、Content-Length | 11 |
| 认证与凭据 | Authorization、Cookie | 11 |
| 缓存与条件请求 | Cache-Control、If-None-Match | 8 |
| 范围请求 | Range、If-Range | 3 |
| 连接与传输 | Connection、Transfer-Encoding | 11 |
| 代理与转发 | X-Forwarded-For、X-Real-IP | 17 |
| 客户端信息 | User-Agent、Referer、Origin | 10 |
| Fetch 元数据 | Sec-Fetch-Site、Sec-Fetch-Mode | 6 |
| CORS 预检 | Access-Control-Request-Method | 3 |
| Client Hints | Sec-CH-UA、Sec-CH-DPR | 19 |
| 网络状况 | Downlink、ECT、RTT | 6 |
| 链路追踪 | traceparent、X-Request-ID | 20 |
| WebSocket | Sec-WebSocket-Key | 5 |
| 云服务与签名 | X-Amz-Date、X-Goog-Api-Key | 10 |
| 自定义扩展 | X-Idempotency-Key、Prefer | 14 |
| 已废弃 | Warning、P3P、X-UIDH | 7 |
一个请求头由三部分组成:
名称: 值
Content-Type、content-type、CONTENT-TYPE 在服务端看来完全等价,按惯例使用 Header-Case 只是为了可读性。text/html;q=0.9)。Name:value 与 Name: value 等价。一个常见的坑:用中文冒号「:」或全角空格书写请求头,服务器会直接解析失败,或把整行当作无效头丢弃。
RFC 9110 把请求头分成两类,这个区别直接影响反向代理的行为:
Accept、Authorization、Content-Type。Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization、TE、Trailer、Transfer-Encoding、Upgrade。所以如果你在 Nginx 里配置 proxy_set_header Connection "",本质上就是在清理逐跳头,避免它被错误地传给上游。
反向代理场景下,后端服务器看到的 REMOTE_ADDR 永远是代理的 IP。为了把真实客户端 IP 传下去,业界约定用 X-Forwarded-For 记录 IP 链路:
X-Forwarded-For: 203.0.113.195, 70.41.3.18, 150.172.238.178
↑ 原始客户端 ↑ 一级代理 ↑ 二级代理
关键点在于:这个头是客户端可以随意伪造的。攻击者只要自己发一个 X-Forwarded-For: 1.2.3.4,你的日志里就会出现假 IP。
正确的取值方式是「从右往左数,跳过所有你信任的代理」:
CF-Connecting-IP 这类由厂商覆盖写入的头。如果直接把 X-Forwarded-For 的第一个值当作客户端 IP 用于风控或限流,等于把限流开关交给了攻击者。
User-Agent 是个历史包袱:格式混乱、各家随意扩展、既暴露隐私又难以解析。浏览器厂商的应对是 UA 缩减(UA Reduction),把 UA 字符串冻结成固定模板:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
注意 Chrome/128.0.0.0——次要版本号被统一填成 0.0.0,真实版本不再暴露。
替代方案是 Client Hints,一套以 Sec-CH- 开头的请求头,按「熵」分级:
Sec-CH-UA、Sec-CH-UA-Mobile、Sec-CH-UA-Platform,足够做基础的浏览器与平台识别;Sec-CH-UA-Platform-Version、Sec-CH-UA-Arch、Sec-CH-UA-Model、Sec-CH-UA-Full-Version-List 等。服务器必须在响应中返回 Accept-CH 列出需要哪些提示,浏览器才会在*后续请求中发送。这种「按需申请」的机制,把「是否暴露指纹」的决定权交还给了服务器与用户代理之间的协商,而不是让每个请求都带上完整指纹。
传统上服务端判断「这个请求是不是跨站伪造」只能依赖 Origin 和 Referer,而这两个头都可能缺失或被策略裁剪。
Sec-Fetch-* 系列由浏览器强制写入,页面脚本无法伪造,这是它最有价值的地方:
| 请求头 | 作用 |
|---|---|
| Sec-Fetch-Site | 发起方与目标的关系:same-origin / same-site / cross-site / none |
| Sec-Fetch-Mode | 请求模式:cors / no-cors / navigate / same-origin |
| Sec-Fetch-Dest | 资源用途:document / script / image / empty |
| Sec-Fetch-User | 是否由用户激活(点击)触发 |
一个典型的加固规则:对写操作接口要求 Sec-Fetch-Site 为 same-origin 或 same-site,拒绝 cross-site;同时对没有该头的请求(老浏览器、脚本客户端)单独走 Token 校验。这样既不影响正常调用,又能挡掉绝大多数浏览器发起的 CSRF。
微服务下,一个用户操作可能横跨十几个服务。追踪头的作用是把「同一次调用」串起来:
traceparent 是 W3C Trace Context 标准,格式为 版本-追踪ID-SpanID-标志位,跨厂商互认,是当前首选;tracestate 配合它传递厂商私有状态;Baggage 用来传递业务上下文(租户 ID、实验分组),让下游服务不必再查库;X-Request-ID 则是最朴素的方案:一个请求一个 ID,贯穿日志即可用检索串起全链路。实践中两者常常并存——X-Request-ID 给运维看日志,traceparent 给 APM 画调用树。
Content-Length 与 Transfer-Encoding: chunked 同时出现:不同实现取值不同,是「HTTP 请求走私」的经典入口,二者必须互斥。headers['Content-Type'] 硬匹配,遇到 content-type 就会取空,解析前应统一转小写。Referer 的拼写:标准里就是 Referer(少一个 r),这是 RFC 沿用的历史笔误,写 Referrer 服务器收不到。Set-Cookie 例外,它必须分行,不能合并。= 和 ;:Cookie: a=b=c; d=e 中只有第一个 = 是分隔符,值里可以含 =,但含 ; 必须编码。X-Forwarded-For 会越来越长,最终触发头部大小限制返回 400 或 431。以上请求头均可直接用于业务开发,复制后按需替换示例值即可。
同名请求头出现多次会怎样?
Cookie 请求头的值里能带分号和等号吗?
traceparent 和 X-Request-ID 该用哪个?
请求头有大小限制吗?
OPTIONS 预检请求里为什么看不到 Authorization 头?
自定义请求头一定要加 X- 前缀吗?
Sec-Fetch- 系列和 Origin 有什么区别?
Sec-CH- 开头的 Client Hints 为什么有些收不到?
为什么我的 Referer 头收不到?
Content-Length 和 Transfer-Encoding 可以同时存在吗?
X-Forwarded-For 能直接用来做限流或风控吗?
请求头名称大小写有区别吗?