HTTP 请求的剖析
每次你点击链接、提交表单或从 API 获取数据时,浏览器都会构造一个 HTTP 请求并通过网络发送。但这个请求究竟由什么组成?理解 HTTP 请求的剖析结构能为你建立一个心智模型,无论你是在调试网络问题、优化性能还是构建 API,这个模型都适用。
本文将分解不同协议版本中的 HTTP 请求结构,并重点介绍前端开发者需要了解的现代 HTTP 头部及其实际影响。
核心要点
- HTTP 请求由三个核心部分组成:请求行(或 HTTP/2+ 中的伪头部)、头部和可选的请求体。
- 请求的语义结构在 HTTP/1.1、HTTP/2 和 HTTP/3 中保持一致。变化的是传输格式和传输机制。
- 现代头部如 Fetch Metadata、Client Hints 和 Priority 为开发者提供了对安全性、隐私和性能的更精细控制。
- Cookie 行为随着
SameSite=Lax默认值和分区 Cookie(CHIPS)的引入而发生了变化,影响了跨站状态的管理方式。
HTTP 请求结构:核心组成部分
HTTP 请求由三部分组成:请求行(或其等效形式)、头部和可选的请求体。
在 HTTP/1.1 中,请求看起来像这样:
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 45
{"username": "dev", "email": "dev@example.com"}
请求行包含方法(POST)、目标路径(/api/users)和协议版本。头部提供元数据——内容类型、身份验证、缓存指令。请求体在需要时承载有效负载。
这个结构在 HTTP/1.1、HTTP/2 和 HTTP/3 中语义上保持完全一致。变化的是这些组件的表示和传输方式。
HTTP/1.1 vs HTTP/2 vs HTTP/3 请求
HTTP/1.1:基于文本和顺序处理
HTTP/1.1 通过 TCP 以纯文本形式传输请求。每个连接上的请求按顺序处理。虽然 HTTP/1.1 支持持久连接(keep-alive)和管道化,但由于队头阻塞问题,浏览器通常避免使用管道化。相反,浏览器通过打开多个并行连接(通常每个源 6 个)来绕过单请求限制。
Host 头部在 HTTP/1.1 中是强制性的——它告诉服务器应该由哪个虚拟主机处理请求。
HTTP/2:二进制帧和多路复用
HTTP/2 将消息封装在二进制帧中,并引入了伪头部来替代请求行:
:method— HTTP 方法:path— 路径和查询字符串:scheme—http或https:authority— HTTP/2+ 中Host头部的等效项,用于标识目标授权机构
多个请求通过多路复用共享单个 TCP 连接。头部通过 HPACK 压缩,消除了在请求间重复相似头部的冗余。
HTTP/3:QUIC 和连接弹性
HTTP/3 使用基于 UDP 的 QUIC 而非 TCP。这消除了传输层的 TCP 队头阻塞——如果一个流停滞,其他流不受影响地继续传输。连接迁移让请求能够在网络变化中存活,这对在 Wi-Fi 和蜂窝网络间切换的移动设备特别有用。
HTTP/3 中的头部压缩使用 QPACK 而非 HPACK,适配了 QUIC 独立流的正确工作方式。
请求语义保持不变。你的代码不需要改变——改变的是传输方式。
Discover how at OpenReplay.com.
重要的现代 HTTP 头部
除了 Content-Type 和 Authorization 等基础头部,还有几个现代头部值得关注:
Fetch Metadata 头部(Sec-Fetch-Site、Sec-Fetch-Mode、Sec-Fetch-Dest)让服务器了解请求的上下文——是同源、跨站,还是由导航触发而非脚本触发。
Client Hints(Sec-CH-UA、Sec-CH-UA-Platform、Sec-CH-UA-Mobile)以结构化、注重隐私的方式提供设备和浏览器信息,减少了许多用例对传统 User-Agent 字符串的依赖。
Priority 头部向服务器发出资源重要性信号,帮助它决定在多路复用连接上优先发送什么,尽管实际支持在不同服务器和 CDN 间有所差异。
对前端开发者的实际影响
性能优先级
Priority 头部(在 RFC 9218 中定义)影响服务器和 CDN 如何排序响应。它用更简单的方案替代了 HTTP/2 时代的流权重和依赖模型,使用 urgency 和 incremental 参数。关键资源如字体或首屏图片可以标记为高优先级,确保它们首先到达。
安全考虑
注意冲突的 Content-Length 和 Transfer-Encoding 头部——这种不匹配可能导致请求走私攻击。服务器应该拒绝模糊的请求,但理解这种风险有助于调试意外行为。
不断演变的 Cookie 模型
现代浏览器中 Cookie 现在默认为 SameSite=Lax,这限制了 Cookie 在跨站子请求中的发送,除非明确配置。分区 Cookie(CHIPS)按顶级站点隔离第三方 Cookie,影响嵌入内容如何管理状态。
结论
HTTP 请求的剖析结构——方法、目标、头部、请求体——在各协议版本间保持一致。变化的是传输格式:HTTP/1.1 中的文本、HTTP/2 中的二进制帧、HTTP/3 中的 QUIC 流。
对于前端工作,重点是在调试 HTTP/2+ 时理解伪头部,利用 Fetch Metadata 和 Client Hints 等现代头部,并了解影响请求行为的安全和 Cookie 变化。协议处理传输复杂性。你的工作是知道实际发送的是什么。
常见问题
在 HTTP/1.1 中,方法、路径和版本出现在纯文本请求行中。HTTP/2 用伪头部如 :method、:path、:scheme 和 :authority 替代了这一行,它们在二进制帧中编码。它们携带相同的信息,但使用 HPACK 压缩更高效地传输。常规头部在 HTTP/2 中仍与伪头部并存。
HTTP/2 在单个 TCP 连接上多路复用流,因此丢失的数据包会阻塞所有流,直到重传完成。HTTP/3 使用基于 UDP 的 QUIC,其中每个流在传输层是独立的。停滞的流不会阻塞其他流,在不可靠的网络上性能更好。
Priority 头部让你能够发出哪些资源最重要的信号。服务器和 CDN 使用它来决定多路复用连接上的传输顺序。将字体或关键图片等关键资源标记为高优先级可以减少感知加载时间。它使用 RFC 9218 中定义的 urgency 和 incremental 参数。
现代浏览器将 Cookie 默认为 SameSite=Lax,这意味着 Cookie 不会在跨站子请求(如从第三方上下文加载图片或 fetch 调用)中发送。它们仍会在顶级导航中发送。要跨站发送 Cookie,必须明确设置 SameSite=None 以及 Secure 属性。
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.