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

Does the browser cancel server push when a resource is in cache?

HTTP/2 规范表明如果客户端取消它,将不会推送在 PUSH_PROMISE 帧中标识的任何资源。

当浏览器检测到缓存中已有资源时,应该取消对该资源的推送。但是,我看不到浏览器如何检测到它。框架是否提供附加信息,如 etag 或上次修改时间,以允许浏览器检测是否必须驱逐任何缓存条目或是否可以取消推送?

如果可能的话,可以节省一些带宽。但是,服务器推送似乎损害了任何客户端缓存优化。

在 HTTP/2 中,服务器向客户端推送一个 请求 以获取具有 PUSH_PROMISE 帧的资源。

从服务器到客户端时,这不是响应,而是请求,客户端为获取该资源而发出的请求。

当客户端收到PUSH_PROMISE时,它可以查看URI,并找出该资源的缓存状态。浏览器通常对正常接收的资源和推送的资源使用不同的缓存。 如果缓存仍然有效,客户端可以通过向该流的服务器发送 RST_STREAM 帧来取消推送的流。

同时,服务器开始推送资源。这将生成一个 HEADERS 响应帧,其中将包含典型的响应 header,例如 etag。 当客户端收到 HEADERS 响应帧时,它还有一次机会取消流,尽管 - 当然 - DATA 帧可能正在运行,可能是所有帧。

节省带宽可能很有趣,但浪费一点带宽通常不是问题;从用户体验的角度来看,更重要的是延迟,而推送机制可以大大减少延迟。

我认为推送机制不会影响任何客户端缓存优化;如果是这种情况,浏览器供应商会反对此功能,而大多数(如果不是全部)浏览器供应商都实现了它,并在用户体验和减少延迟方面取得了非常好的结果。

当然可以改进该机制,例如让客户端和服务器就一些 header 达成一致,这将提供有关被推送资源的更多信息,但到目前为止效果还不错。

[免责声明:我是 Jetty 提交者] 是第一个为 Java 生态系统实施 SPDY 和 HTTP/2 Push 的人(almost 3 years ago), the Jetty Project is certainly interested in more discussions and ideas around HTTP/2 Push。

简单而简短的回答:是的,如果缓存中有此 URL,浏览器将取消服务器推送