javascript - 识别 Service Worker 缓存中的陈旧缓存条目

标签 javascript http caching browser-cache service-worker

我希望我的 Service Worker 在某些情况下表现得像浏览器缓存一样。这意味着当响应缓存命中时,我首先需要确保资源没有过期。例如,我可以这样做:

const cacheControl = response.headers.get('cache-control');
const date = new Date(response.headers.get('date'));
const age = parseInt(response.headers.get('age') || '0', 10);

const maxAge = getMaxAge(cacheControl);
const expiration = date.getTime() + 1000 * (maxAge - age);

const isFresh = Date.now() < expiration;

我从缓存的响应中获取 cache-controldateage header ,计算过期时间并与当前时间进行比较。

这种方法的唯一问题是它可能会受到客户端和服务器之间时钟漂移的影响。这是因为日期头是在服务器端生成的,但最终与本地客户端时间进行比较。

想象一下,客户端时间延迟了一天(不幸的是有时会发生),现在缓存条目的缓存时间可能比预期长或短一天。

我想要的解决方案是在缓存中存储响应时将获取时间添加为自定义 header 。然后我可以使用这个自定义 header 而不是

const networkResponse = fetch(request);
// does not work, headers are immutable
networkResponse.headers.append('x-time-fetched', Date.now());
cach.put(request, networkResponse);

遗憾的是,这个解决方案不起作用,因为网络响应是不可变的。顺便说一句:复制响应以添加此附加信息不是一种选择。

有人知道如何像浏览器一样正确识别过时的缓存条目吗?

最佳答案

Sadly, this solution does not work because the network response is not mutable. Btw: copying the response to add this additional information is not an option.

这实际上是非常可行的。

一个解决方案是创建一个新的 Response object并手动添加新 header 。

const newHeaders = new Headers()
for (let entry of response.headers.entries()) {
  headers.append(entry[0], entry[1])
}
headers.append('x-time-fetched', Date.now())

const newResponse = await response.blob().then(blob => {
  return new Response(blob, {
    status: response.status,
    statusText: res.statusText,
    headers: headers
  })
})

另一个更简单但有难度的解决方案是在响应对象上创建一个新属性,而不是依赖于 header 对象:

response.__time_fetched = new Date()

关于javascript - 识别 Service Worker 缓存中的陈旧缓存条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50834217/

相关文章:

http - 区分 Restful Web 服务中无结果和无服务

java - 编写一个简单的 HTTP 服务器来接受 GET 请求

java - 错误 :Could not download artifact 'com.android.tools.build:gradle:0.13.2:gradle.jar' : No cached version available for offline mode

caching - 我的页面是否必须具有 HTML5 文档类型才能访问 sessionStorage

javascript - Rails ajax 第一次执行调用

javascript - 从另一个页面链接到特定选项卡

perl - 在将请求从安全服务器重定向到非安全服务器期间,来自 PERL 脚本的 HTTP 错误 508

javascript - Node.js 从回调函数中提取值

javascript - 如何根据浏览器大小调整我的 div 的高度

javascript - 如何在 Javascript 中缓存 XMLHttpRequest 响应?