在 service worker / fetch() 中识别 HTTP 304

Recognize HTTP 304 in service worker / fetch()

我构建了一个 service worker,它始终响应缓存中的数据,然后在后台向服务器发送请求。如果服务器响应 HTTP 304 - not modified 一切正常,如果服务器响应 HTTP 200,这意味着数据已更改并且新文件已放入缓存中,同时还会通知用户并要求页面刷新。

我使用 not-modified-since / last-modified header 来确保客户端获得最多 up-to-date 版本。当通过 fetch() 发送请求时,请求在到达网络的途中通过 HTTP-cache - 当响应到达客户端时,响应也会通过 HTTP 缓存。问题是当响应的状态为 304 - 未修改时,HTTP 缓存使用缓存版本响应服务工作者,并将状态替换为 200(如 [=30= 中所述) ]).在 service worker 中,无法确定 200 响应最初是由服务器发送的(用户需要更新)还是由缓存发送并且服务器最初以 [=15= 响应](大多数 up-to-date 版本已加载)。

有一个cache-mode flag可以设置为no-cache,但是这样在向服务器发送请求时也会绕过HTTP-cache,也就是说if-modified-since header 未设置,服务器没有机会找出客户端的版本。此外,目前只有 firefox nightly 支持此标志。

我认为最好的解决方案是在服务器响应 200 时设置自定义 HTTP header,如 x-was-modified。这个自定义 header 可以在 service worker 中访问,并且可以用来查明资源是否已更新 - 即使 HTTP 缓存将 304 状态替换为 200

您不能依赖状态代码(304 与 200)来确定是否发生了某些变化。如果您的代码的其他部分请求相同的资源,从而更新浏览器的缓存怎么办?

相反,只需将响应的 Last-Modified header 与您在 If-Modified-Since 中发送的内容或您在 Last-Modified 中最后看到的内容进行比较。如果值不匹配,则说明发生了某些变化。

为了更精确(如果数据可以在 1 秒内更改多次),请考虑使用 ETag 而不是 Last-Modified

Why does fetch() even replace the 304 code with 200 if there is a up-to-date version in the cache?

因为通常人们只想获得新鲜的内容,而不管它来自哪里。 304 响应仅对那些实现自己的 HTTP 缓存的人感兴趣。