【问题标题】:HTTP2 does not yet support etags?HTTP2 还不支持 etags?
【发布时间】:2019-10-02 21:18:39
【问题描述】:

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

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

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

【问题讨论】:

  • 我认为您误解了它的工作原理。当您推送文件时,客户端不会发送任何标头,因为客户端不会请求该文件。服务器发送一个 PUSH_PROMISE 帧说“仅供参考,我将推送这个资源,就好像你这样要求它一样”,然后发送响应头和正文。所以不需要支持 ETag,因为没有客户端请求,所以 IF-NONE-MATCH 可以匹配。
  • 我明白,我对服务器发送的标头感到困惑。尽管如此,在我看来,发送已经在客户端中的信息是一种浪费带宽。据我了解,客户端有两次拒绝推送的机会,第一次拒绝promise,然后发送一个帧RST_STREAM。没有机制可以避免这种行为,而是利用推送的潜力?
  • 我已经在下面给出了详细的答案。请注意,拒绝 PUSH_PROMISE 是通过 RST_STREAM 完成的,因此只有一种拒绝推送的方法,而不是您建议的两种。

标签: http2 etags


【解决方案1】:

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

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

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

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

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

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

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

便宜的插件,但如果对此感兴趣,那么我的recently published book 中的Chapter 5 会更详细地讨论这一切,然后可以挤进 Stack Overflow 上的答案。

【讨论】:

  • 谢谢!我是堆栈的新手,我急于做最初的提问。你的回答澄清了我的疑惑和怀疑。另请注意,大多数情况下,Chrome 不可避免地会通过推送和浏览器分析器下载相同的资源,而不管缓存应用程序如何。在这种情况下,我不明白的是,浏览器没有发送 RST_STREAM 帧,而是根本不避免发送或停止来自浏览器分析器的新请求。目前我将继续在我的服务器上支持 HTTP2,但我会降低推送功能。
  • 浏览器不应请求正在推送的项目。正如我链接的那篇文章 (jakearchibald.com/2017/h2-push-tougher-than-i-thought) 中所详述的那样,在某些情况下发生这种情况,字体是不应该被推送的东西,但是通常在浏览器看到 PUSH_PROMISE 框架之后,它就会知道资源正在路上并持有不再请求它。
猜你喜欢
  • 2020-04-30
  • 2015-10-20
  • 2016-05-23
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
  • 2022-11-18
  • 1970-01-01
  • 2017-03-30
相关资源
最近更新 更多