首页 > 解决方案 > HTTP2 还不支持 etags?

问题描述

我目前正在使用 Node.js 为动态和静态文件制作服务器。我正在尝试实现 HTTP2。让我吃惊的是,HTTP2 推送似乎不支持 ETags!

当客户端发送标头以检索以推送开头并已接受的文件时,它会忽略“IF-NONE-MATCH”标头。

这是一种浪费,我不明白这种行为的原因。是这种情况还是我错过了什么?

标签: http2etags

解决方案


正如评论中所讨论的,服务器推送资源,所以没有客户端请求,所以没有 Etag 发送。

所以 HTTP/2 确实支持 Etags——它们只是与推送请求无关。

是的,这确实意味着对于 Pushed 资源会忽略缓存资源——这是 Push 的一大缺点,也是为什么很多人不建议使用它的原因。当客户端在推送资源之前看到服务器发送的 PUSH_PROMISE 时,它可以使用 RST_STREAM 请求拒绝它,但到将其发送到服务器时,通常大部分(如果不是全部)资源已经被推送.

有几种方法可以解决这个问题:

  1. 例如,您可以使用 cookie 跟踪已推送的内容。我在这里有一个 Apache 配置的简单示例:https ://www.tunetheweb.com/performance/http2/http2-push/ 。当然,这假设 cookie 和缓存是同步的,但它们可能不同步(它们可以独立清除)。
  2. 一些服务器会跟踪已经推送的内容。例如,Apache允许配置 HTTP/2 推送日志(默认设置为 256 个项目),以跟踪在该连接上推送的项目。如果您访问 page1.html 并推送 styles.css,然后您访问 page2.html 并且它也尝试推送 styles.css Apache 不会推送它,因为它知道您已经拥有它。但是,仅当您使用相同的连接时才有效。如果您稍后在新连接上返回,但它仍在缓存中,那么它将被重新推送。
  3. 有一个关于缓存摘要的提议,它允许浏览器在任何连接开始时发送缓存中内容的编码列表,服务器可以使用它来知道是否推送项目。然而,这方面的工作最近已经停止,因为对此存在一些隐私问题。

最终,事实证明 HTTP/2 Push 很难发挥作用,因此它的使用率非常低。很大程度上是因为这个,也因为它很复杂,还有其他的隐含问题。即使所有这些都解决了,当最好让浏览器按照它知道需要它们的顺序请求资源时,仍然很容易过度推送资源。Chrome 团队甚至讨论过关闭它而不支持它。

许多人建议使用状态码为 103的早期提示,因为它告诉浏览器请求什么,而不仅仅是推送它。然后浏览器可以使用所有它通常的知识(缓存中有什么,应该以什么优先级请求它......等等),而不是像 Push 那样覆盖所有这些。

便宜的插件,但如果对此感兴趣,那么我最近出版的书的第 5 章会更详细地讨论这一切,然后可以挤进 Stack Overflow 上的答案。


推荐阅读