浏览器如何知道发送请求时应该使用哪个版本的 HTTP?

oet*_*ter 17 browser google-chrome http

当浏览器第一次向服务器发送请求时,它如何决定应该应用哪个版本的 HTTP?HTTP RFC 规范说:

HTTP 客户端应该发送等于客户端至少有条件兼容的最高版本的请求版本

但根据我在 Chrome 检查器中的实验,Chrome 在向某些网站发送请求时使用 HTTP 2,但在其他情况下也使用 HTTP 1.1。

我想知道 Chrome 如何知道它应该使用哪个版本的 HTTP 请求?我知道服务器应该使用它支持的最高版本的 HTTP 进行响应,那么 Chrome 是否会默认使用 http2 向每个网站发送第一个请求,然后保存网站支持的 HTTP 版本并从此使用该版本?

任何解释将不胜感激。

use*_*686 23

HTTP/1.x

\n

HTTP/1.1 和 HTTP/1.0 都使用兼容的请求格式。在第一个请求之后,服务器的响应将指示它支持的版本,以及诸如“Connection: keep-alive”之类的标头,指示可以使用哪些功能。

\n

HTTP/2

\n

浏览器决定仅通过 TLS 连接支持 HTTP/2。这使他们能够使用称为 ALPN(应用层协议协商)的新 TLS 功能。

\n

当 Chrome 建立 TLS 连接时,它会在 TLS 握手过程中发送支持的协议列表 (http/1.1和),并且服务器会使用它希望使用的协议进行响应 \xe2\x80\x93 例如“h2”,表明它\'h2现在期待 HTTP/2。

\n

如果服务器根本不返回 ALPN 扩展,浏览器会假定它只支持 HTTP/1.x。(这就是为什么在服务器上启用 HTTP/2 支持需要升级 OpenSSL 的原因。)

\n
\n

HTTP/2 协议本身确实支持通过使用 HTTP升级机制在明文连接上使用。在大多数情况下,第一个请求必须是 HTTP/1.1,标Upgrade:头再次列出客户端想要切换到的协议。

\n

响应也将是 HTTP/1.1,要么是“101 Switching Protocols”,表明服务器现在期望在相同连接上使用 HTTP/2,要么是其他表明不支持 HTTP/2 的内容。

\n

浏览器不以这种方式使用 HTTP Upgrade,它们根本不支持没有 TLS 的 HTTP/2。(但是,Apache HTTPD Web 服务器可以配置为接受“h2c”连接进行测试。)

\n

HTTP/3

\n

HTTP/3 使用不同的传输协议(QUIC 与 TCP),因此无法进行内联升级。浏览器不知道服务器是否支持 QUIC,因此它仍然会建立初始 TCP 连接并使用 TLS ALPN 协商 HTTP/1.1 与 HTTP/2,如上所述。

\n

升级到 HTTP/3 实际上是服务器发起的 \xe2\x80\x93 在其 HTTP 响应中服务器发送Alt-Svc 标头(或 HTTP/2 中的特殊 ALTSVC 帧)表明它在指定的服务器上支持 HTTP/3 UDP/QUIC 端口。浏览器可能会遵循该建议并尝试建立 QUIC 连接,如果成功则关闭 TCP 连接。

\n