为什么 HTTP/2 使用 Pseudo-Header 字段?

Why HTTP/2 uses Pseudo-Header Fields?

来自 RFC7540:

While HTTP/1.x used the message start-line (see [RFC7230], Section 3.1) to convey the target URI, the method of the request, and the status code for the response, HTTP/2 uses special pseudo-header fields beginning with ':' character (ASCII 0x3a) for this purpose.

那么为什么 HTTP/2 使用 Pseudo-Header 字段? HTTP/1.x 中的消息 start-line 有什么问题吗?

借用来自Google's introduction to HTTP/2

的图片

在这张图片中,您可以看到在第一个请求中,前两行 header 通常是这样的:

GET /resoure HTTP/1.1
Host: https://example.com
...

现在像这样分成 header 帧

:method: GET
:scheme: https
:host: example.com
:path: /resource
...

而其余 header 大致相同,除了都是 lower-case 个字符。

HTTP/2 尝试尽可能减少负载大小。它还将压缩 headers 和剥离 headers 等于上一个请求中发送的 headers,如链接图像的右侧部分所示。

在 HTTP/1.1 中,一个连续的请求看起来像是针对不同资源的第一个初始请求:

GET /otherResource HTTP/1.1
Host: https://example.org
...

而在 HTTP/2 中,对同一服务器的连续请求只需要

:path: /otherResource

因为所有其他 header 都已经可用并且可以从之前缓存和索引的 header 中恢复。

因此,这是一项优化,可进一步减少连续请求的负载。

HTTP/2为新协议,采用二进制编码。

HTTP/2 中没有状态行,就像个人 header 没有 'lines' 一样。必须发明一种全新的方法来对 HTTP 请求的每个部分进行编码。

Headers 实际上是一个键->值结构。与其为出现在 HTTP/1.1 请求的第一行的内容发明不同的编码,不如对这些内容使用相同的编码方法使协议更简单。

毕竟像'path'和'http method'这样的东西已经在header中了,为什么不采用相同的编码方法他们作为常规 headers。前面的 : 确保不会与现有的 HTTP/1.1 header 发生冲突,因为 header 的名称永远不能包含 :.

所以 tl;dr 是:通过将 HTTP 请求和响应的第一行信息编码为特殊 HTTP headers,协议可以更简单。