在 HTTP/1.x 中,每个请求都会携带完整的 Header 字段(如 User-Agent、Cookie 等),即使多个请求的 Header 变化不大,也需要重复发送,导致大量带宽浪费。
HTTP/2 引入了 HPACK 头部压缩算法,通过表格存储和差量更新,减少 Header 体积,提高传输效率。
关键点
通讯双方(客户端 & 服务端)各自维护一张动态表,缓存 Header 信息。
后续请求不再传递完整头部,只传递索引或增量变化。
使用 Huffman 编码压缩 Header 字段值,进一步减少大小。
具体流程
首次请求:完整发送头部字段
客户端 -> 服务端:发送完整的 Header 并存入动态表。
服务器收到后,同样存入动态表。
后续请求:只发送变化部分(索引 + 差量更新)
如果 Header 完全相同,客户端只发送索引(减少重复数据)。
如果 Header 部分字段变化,客户端仅发送新增或修改的部分。
服务器收到后,更新自己的动态表,按需修改 Header。
动态表初始为空:
索引 | Header Name | Header Value |
---|---|---|
(空) | (空) | (空) |
说了上面这些,我们有了初步了解,接下来通过例子来加深印象。
第 1 次请求(完整 Header)
请求:
GET /index.html HTTP/2Host: example.comUser-Agent: Chrome/100Accept-Encoding: gzipCookie: session=abc123
由于动态表为空,客户端完整发送 Header。
服务器接收 Header 后,会依次存入动态表(新项在表头)。
动态表(服务器端更新):
索引 | Header Name | Header Value |
---|---|---|
1 | Cookie | session=abc123 |
2 | Accept-Encoding | gzip |
3 | User-Agent | Chrome/100 |
4 | Host | example.com |
第 2 次请求(部分 Header 相同,内容变化)
请求:
GET /about.html HTTP/2Host: example.comUser-Agent: Chrome/100Accept-Encoding: gzipCookie: session=xyz456
变化点:
Host、User-Agent、Accept-Encoding 未变(可以直接用索引)。
Cookie 变了(session=xyz456),需要发送新的值,并更新动态表。
客户端优化发送(使用索引 + 变更值):
索引4 # Host: example.com索引3 # User-Agent: Chrome/100索引2 # Accept-Encoding: gzip(新值) Cookie: session=xyz456
动态表(服务器端更新):
索引 | Header Name | Header Value |
---|---|---|
1 | Cookie | session=xyz456 (替换旧值) |
2 | Accept-Encoding | gzip |
3 | User-Agent | Chrome/100 |
4 | Host | example.com |
客户端只发送 1 个新字段,其余字段直接用索引代替,减少了数据传输量。
第 3 次请求(部分 Header 继续变化,新增字段)
请求:
GET /profile.html HTTP/2Host: example.comUser-Agent: Chrome/100Accept-Encoding: gzipCookie: session=xyz456Authorization: Bearer 12345 # 新增字段
变化点:
Cookie 未变(使用索引)。
Authorization 是新字段(需要传输并更新动态表)。
客户端优化发送:
索引4 # Host: example.com索引3 # User-Agent: Chrome/100索引2 # Accept-Encoding: gzip索引1 # Cookie: session=xyz456(新值) Authorization: Bearer 12345
动态表(服务器端更新):
索引 | Header Name | Header Value |
---|---|---|
1 | Authorization | Bearer 12345 (新增) |
2 | Cookie | session=xyz456 |
3 | Accept-Encoding | gzip |
4 | User-Agent | Chrome/100 |
5 | Host | example.com |
好了,通过上面的例子,你多多少少应该懂了,接下来总结一下。
总结
HTTP/2 通过 HPACK 机制压缩 Header,缓存已发送字段,并在后续请求中只传递差量数据。
通讯双方(客户端 & 服务端)各自维护一个动态表,避免重复发送相同头部字段,提升传输效率。
头部字段采用 Huffman 编码进一步压缩,减少宽带占用。
最后如果觉得文章对你有帮助,记得给个赞,感谢~