我知道浏览器可以发送RST_STREAM-frames
来取消serverpush
。
在Last-Modified
内发送Etag
或PUSH_PROMISE
标头是否有意义?
或者是to-be-pushed
资源的验证仅基于他们的URI
(两年前Simone Bordet回答了以下问题)?
Does the browser cancel server push when a resource is in cache?
我无法找到这个问题的确切答案。
答案 0 :(得分:0)
当HTTP / 2服务器推送资源时,它会生成要发送到客户端的PUSH_PROMISE
帧,同时它会创建一个合成请求,该请求将被处理,就像远程客户端发送它一样。 / p>
请注意,PUSH_PROMISE
框架代表客户端为该资源制作的请求,而不是响应。
通常,Last-Modified
框架标头的内容和合成请求的标头是相同的,但是 - 根据实施情况 - 可能不是这种情况。
标题ETag
或PUSH_PROMISE
仅在回复中有意义,因此将它们添加到If-Modified-Since
框架是没有意义的。
将PUSH_PROMISE
等其他请求标头添加到If-Modified-Since
是否有意义取决于是否将相同的标头用于合成请求。
如果使用相同的标头(通常是这种情况),则添加标头(例如304 Not Modified
)仅对服务器端处理产生影响:服务器在处理时可能会生成PUSH_PROMISE
合成要求。
但是,服务器为资源发送304
,然后是PUSH_PROMISE
会很奇怪。如果服务器知道客户端已经缓存了资源,那么它也可以跳过发送Last-Modified
。
将响应标头PUSH_PROMISE
添加到PUSH_PROMISE
框架没有意义,因为If-Modified-Since
表示请求。
添加条件请求标头(例如304
)通常要求服务器了解以前为客户端提供的资源:它必须知道资源是否已经过服务因此,向客户端发送推送资源的list(set(it.permutations([1, 1, 1])))
# [(1, 1, 1)]
将使客户端使用其缓存中已存在的资源。
答案 1 :(得分:0)
在深入搜索后,我想我找到了答案:
pushBuilder's
Api对.lastModified()
说:
设置用于条件推送的最后修改日期。
和.etag()
:
设置用于条件推送的etag。
我误解了这些解释和想法,指定的值被发送到PUSH_PROMISE
内的浏览器,以帮助它决定是接受推送文件还是取消流(通过发送RST_STREAM
)。
事实上,这些值似乎告诉服务器,如果它必须推动某事。或不。通过将文件last-modified-date
设置为.lastModified()
,我得到了Simone Bordet在上面的评论中描述的行为:即使文件不存在于我的缓存中,也发送了304
现在,我们已经完全明白,在不知道客户端缓存中的确切内容的情况下设置这些值是没有意义的。
PUSH_PROMISE
中的条件标题似乎现在不存在:
我在HTTP2规范中找不到任何相关内容,在阅读chrome的问题跟踪器时,我发现Tom Bergan在一个开放的(02.01.2017)问题(https://bugs.chromium.org/p/chromium/issues/detail?id=232040#c62)上发表评论:
... 我认为处理这种情况的更好方法是在推送的响应与缓存的资源匹配时将推送的响应转换为304。有两种可能的实现方式:
在收到推送的响应标头之后不要取消推送(因为响应标头包含ETag和/或Last-Modified)。如果推送的资源已被缓存,则浏览器会将推送的响应转换为304并取消推送。然而,国际海事组织,这等待太长时间才能取消推动。
- 醇>
将像If-Match这样的条件标头添加到PUSH_PROMISE,以便浏览器确切知道正在推送哪个资源。这是一个好主意,但在我们实施之前需要进行规范。 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#
如果我说错了,请纠正我。