ServiceWorker / 缓存 / 设置 TTL

ServiceWorker / Cache / Set TTL

关于这个 api https://developer.mozilla.org/en-US/docs/Web/API/Cache,我还想设置 cache lifetime

假设,cache this request for no longer than 10 minutes

不幸的是,这是不可能的。

您链接的文档明确指出缓存 API 提供的缓存对象中的项目不会自动更新或删除。您必须自己实现这种逻辑。

您应该注意库,例如。 Workbox 已经为您做到了。如果其他功能适合您的用例,您可以利用它。

https://developers.google.com/web/tools/workbox/

这就是我在没有 Workbox. (If you can switch to Workbox 的情况下实现它的方式,如果没有,请继续阅读)

  • 创建了一个缓存策略,其中 onFetchComplete 克隆来自网络的响应,添加时间戳 header 比如 x-sw-cache-timestamp.
  • 将此克隆的更新响应存储到缓存中。
  • onCacheMatch 将 x-sw-cache-timestamp 与 currentTime 进行比较,如果超过 10 分钟 window,则从网络获取。
function onFetchComplete(response) {
  var timestampHeader = {}
  timestampHeader['x-sw-cache-timestamp'] = Date.now()

  return serviceWorker
    .cloneResponse(response, timestampHeader)
    .then(function (responseCopy) {
      cache.add(request, responseCopy.clone())
      return responseCopy
    })
}

serviceWorker.cloneResponse = function (response, extraHeaders) {
  if (!response) {
    return serviceWorker.Promise.resolve()
  }

  var init = {
    status: response.status,
    statusText: response.statusText,
    headers: extraHeaders || {},
  }

  response.headers.forEach(function (val, key) {
    init.headers[key] = val
  })

  return response.blob().then(function (blob) {
    return new serviceWorker.Response(blob, init)
  })
}

希望对您有所帮助!

您可以动态创建编码其创建时间和最长期限的缓存名称,简单如:${dateStr}_${maxAgeMs}。然后当在你的 service worker 中拦截一个 fetch 时,你可以使用 caches.keys 查看现有的缓存并找到一个没有过期的只使用它的名字并与之匹配,或者如果它们都过期则创建一个新的并用传入的提取填充它。这也让您有机会删除过期的缓存。

我也需要这样做,并查看了提到的 workbox 项目,似乎他们正在对 IndexedDB 存储做类似的事情,但这似乎有点过分了。