这https://en.wikipedia.org/wiki/HTTP/2#Encryption说
为HTTP URI(即没有加密)和HTTPS URI(在TLS上,需要TLS 1.2或更新版本)定义HTTP / 2。[25]
但在Google上测试我会得到不同的结果:
curl --http2 -I http://www.google.co.uk
HTTP/1.1 200 OK
curl --http2 -I https://www.google.co.uk
HTTP/2 200
其他领域也是如此。有什么解释吗?
答案 0 :(得分:3)
原因是所有浏览器出于各种原因决定仅以加密模式(h2
)支持HTTP / 2。
因此,大多数工具(库,Web服务器,cli工具等)也专注于通过ALPN支持HTTP / 2 over TLS,并且大多数情况下不支持未加密的变体(h2c
) HTTP升级或事先了解HTTP / 2。
在您的情况下卷曲seems to support HTTP/2 upgrade requests,但谷歌网络服务器没有。
答案 1 :(得分:2)
HTTP / 2可以通过未加密的通道(称为h2c)协商,但它更复杂,因为客户端如何知道服务器是否会理解相对较新的HTTP / 2协议?另外,代理服务器在发送未加密的协议时通常会遇到处理此类新协议的问题,但在加密发送时处理它们很好(因为在这种情况下他们无法看到它使用新协议)。
对于加密连接,在发送第一个HTTP请求之前,使用ALPN扩展(或它已替换的旧NPN扩展)协商HTTP / 2(加密时称为h2)作为HTTPS协商的一部分。
对于未加密的连接,没有HTTPS协商,有两个选项:
假设服务器说HTTP / 2并立即开始说HTTP / 2。这有点推测,但理论上如果你失败了,如果你回到HTTP / 1会有效。在许多方面,它类似于关于使HTTPS默认并回退到HTTP的讨论 - 它需要临界质量才能使其变得有价值。
将初始请求作为HTTP / 1请求发送,并使用upgrade: h2c
HTTP标头(以及基本64 HTTP / 2设置帧作为另一个HTTP标头)。这会询问服务器是否可以切换到HTTP / 2以进行下一个请求。服务器应该使用类似的升级头发送HTTP / 1响应,此时下一个请求可以作为HTTP / 2请求发送。此过程详见HTTP/2 spec in section 3.2。
Curl目前仅支持第二种方法,如下所述:https://curl.haxx.se/docs/http2.html因此不会立即说出HTTP / 2。如果您为详细模式运行curl -v
,那么您应该看到升级标头。
然而none of the mainstream web browsers support HTTP/2 over unencrypted channels(h2c)使h2成为事实上的标准 - 至少对于打算供Web浏览器使用的面向公众的服务器而言。因此,许多网络服务器同样选择不打扰实施h2c,因为它将很少使用。见this page to see how few implementations support h2c。 Google的服务器通常由GFE(Google Front End)提供支持,您可以从该列表中看到它只支持h2而不支持h2c。