1

我知道浏览器可以发送RST_STREAM-frames取消serverpush

Last-Modified在 中发送或Etag标头是否有意义PUSH_PROMISE?还是to-be-pushed仅基于资源的验证URI(正如两年前 Simone Bordet 对以下问题的回答)?

当资源在缓存中时,浏览器是否取消服务器推送?

我找不到这个问题的确切答案。

4

2 回答 2

1

当 HTTP/2 服务器推送资源时,它会生成PUSH_PROMISE要发送给客户端的帧,同时它会创建一个合成请求,就像远程客户端发送它一样处理该请求。

请记住,PUSH_PROMISE框架代表客户端对该资源的请求,而不是响应。

通常,PUSH_PROMISE帧标头的内容和合成请求的标头是相同的,但是 - 取决于实现 - 可能并非如此。

标题Last-ModifiedETag仅在响应中有意义,因此将它们添加到PUSH_PROMISE框架中没有意义。

添加其他请求标头是否有意义取决于合成请求是否使用相同的标头If-Modified-SincePUSH_PROMISE如果使用相同的标头(通常是这种情况),则添加诸如此类的标头If-Modified-Since仅对服务器端处理产生影响:服务器可能会304 Not Modified在处理合成请求时生成一个。

但是,服务器发送一个PUSH_PROMISE资源的 a 后跟一个304. 如果服务器知道客户端已经缓存了资源,它也可以跳过发送PUSH_PROMISE.

添加响应标头(例如帧)没有意义,因为 aLast-Modified代表请求。PUSH_PROMISEPUSH_PROMISE

添加条件请求标头,例如If-Modified-Since通常要求服务器了解以前向客户端提供过哪些资源:它必须知道资源是否已经被提供,以便向304客户端发送推送资源的请求将使客户端使用已存在于其缓存中的资源。

于 2017-12-30T20:37:02.773 回答
1

在深入搜索之后,我想我找到了答案:

ApipushBuilder's说:.lastModified()

设置用于条件推送的最后修改日期。

.etag()

设置要用于条件推送的 etag。

我误解了那些解释并认为,将指定的值发送到浏览器内部,PUSH_PROMISE以帮助它决定是接受推送的文件还是取消流(通过发送RST_STREAM)。

事实上,这些值似乎告诉服务器,如果它必须推送某事。或不。通过将文件设置为last-modified-dateas .lastModified(),我得到了 Simone Bordet 在上面的评论中描述的行为:发送了 304,即使该文件不存在于我的缓存中。

所以现在很清楚,在不确切知道客户端缓存中的内容的情况下设置这些值是没有意义的。

a 中的条件标头之类的东西PUSH_PROMISE现在似乎不存在:我在 HTTP2 规范中没有找到任何关于它的内容,并且在阅读 chrome 的问题跟踪器时,我发现 Tom Bergan 在一个开放的(02.01.2017)问题上对此发表了评论(https://bugs.chromium.org/p/chromium/issues/detail?id=232040#c62):

...我认为处理这种情况的更好方法是在推送响应与缓存资源匹配时将推送响应转换为 304。有两种可能的实现:

  1. 在收到推送的响应标头之前不要取消推送(因为响应标头包含 ETag 和/或 Last-Modified)。如果推送的资源已经被缓存,浏览器会将推送的响应转换为 304 并取消推送。但是,IMO,这等待太长时间才能取消推送。

  2. 向 PUSH_PROMISE 添加条件标头(如 If-Match),以便浏览器准确知道正在推送哪个资源。这是一个好主意,但在我们实现它之前需要对其进行规范。 https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0522.html ...

所以我期望的可能(帮助浏览器通过读取发送的一些标头信息来检查缓存资源的有效性PUSH_PROMISE)现在是不可能的,但最终会的。除此之外,似乎cache-digest将来会在浏览器中实现,效果会更好,因为可以避免在服务器上进行不必要的推送。Chrome 已经在处理这个问题,可以在这里看到:https ://docs.google.com/document/d/1HhmyzKUPuWcCs8wG_GLSu3mvptygXtO2mBl5xlmEB-4/edit#

如果我说错了,请纠正我。

于 2018-01-02T14:32:47.880 回答