高级前端http【Q273】http2 中的首部压缩的实现原理是什么

http2 中的首部压缩的实现原理是什么

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 275

Author 回答者: shfshanyue

HPACK 协议,其中原理是哈夫曼编码索引表 (看来常用的数据结构及算法要有所了解),以下内容摘自 谷歌开发者文档:http2

每个 HTTP 传输都承载一组标头,这些标头说明了传输的资源及其属性。 在 HTTP/1.x 中,此元数据始终以纯文本形式,通常会给每个传输增加 500–800 字节的开销。如果使用 HTTP Cookie,增加的开销有时会达到上千字节。 (请参阅测量和控制协议开销。) 为了减少此开销和提升性能,HTTP/2 使用 HPACK 压缩格式压缩请求和响应标头元数据,这种格式采用两种简单但是强大的技术:

  1. 这种格式支持通过静态霍夫曼代码对传输的标头字段进行编码,从而减小了各个传输的大小。
  2. 这种格式要求客户端和服务器同时维护和更新一个包含之前见过的标头字段的索引列表(换句话说,它可以建立一个共享的压缩上下文),此列表随后会用作参考,对之前传输的值进行有效编码。

实践出真知,通过 wireshark 抓包分析 http2 的报文对理解 http2 收益颇多。

你要有知识,你就得参加变革现实的实践。你要知道梨子的滋味,你就得变革梨子,亲口吃一吃。你要知道原子的组织同性质,你就得实行物理学和化学的实验,变革原子的情况。你要知道革命的理论和方法,你就得参加革命。

以下是关于抓包信息的截图

http2 通过 Settings 帧设置 header table size,进行首部压缩

HTTP2 Settings

http2 通过首部压缩后,:method 伪标头在索引表中的 Index 为 2

HTTP2 Index

关于常用的标头会存储在静态索引表固定的位置,详见 https://httpwg.org/specs/rfc7541.html#static.table.definition

Author 回答者: Echo-MakeGreatEffort

HTTP/2 中的首部压缩(Header Compression)是通过一种叫 HPACK 的压缩算法实现的。流程:

  1. 初次请求时,客户端会发送完整的首部字段,但会将首部存储在动态表中。
  2. 之后的请求中,客户端只需要发送动态表中的索引值,服务器可以通过该索引找到对应的首部字段。
  3. 同时,Huffman 编码用于进一步压缩首部字段中的字符

HPACK 实现的几个关键原理:

  1. 静态和动态表:(1)静态表:HTTP/2 预定义了一组常见的 HTTP 首部名称和值对的静态表。该表是固定的,客户端和服务器都可以共享,减少重复传输常见的首部字段 (2)动态表:客户端和服务器各自维护一个动态表,用来存储之前传输的首部名称和值对
  2. 首部字段可以通过索引的方式引用静态表或动态表中的条目