【问题标题】:ServiceWorker / Cache / Set TTLServiceWorker / 缓存 / 设置 TTL
【发布时间】:2019-04-17 13:58:41
【问题描述】:

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

比方说,cache this request for no longer than 10 minutes

【问题讨论】:

    标签: javascript service-worker browser-cache service-worker-events


    【解决方案1】:

    很遗憾,这是不可能的。

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

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

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

    【讨论】:

    • 使用 Workbox 设置,过期的服务工作者仍将显示一次,但随后 the plugin will check and remove entries after each request or cache update. Because it’s slow to open IndexedDB, expiration won’t occur until after the request is used. This means that an expired request may be used once, but will be expired after that. 所以据我了解,这并没有真正为服务工作者本身设置过期日期,而只是刷新然后。相关链接为:developers.google.com/web/tools/workbox/modules/…
    【解决方案2】:

    这就是我在没有Workbox 的情况下实现它的方式。 (如果你可以切换到Workbox,请这样做,如果不能——请继续阅读)

    • 创建了一个缓存策略,该策略 onFetchComplete 会克隆来自网络的响应,并添加一个时间戳标头,例如 x-sw-cache-timestamp
    • 将此克隆的更新响应存储到缓存中。
    • onCacheMatch 将x-sw-cache-timestamp 与 currentTime 进行比较,如果超过 10 分钟窗口,则从网络获取。
    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)
      })
    }
    

    希望这会有所帮助!

    【讨论】:

      【解决方案3】:

      您可以动态创建缓存名称,对它们的创建时间和最大年龄进行编码,例如:${dateStr}_${maxAgeMs}。然后,在您的服务工作者中拦截一个提取时,您可以使用caches.keys 查看现有缓存,并仅使用其名称找到一个未过期的缓存并与之匹配,或者如果它们都已过期并填充,则创建一个新缓存它与传入的提取。这也让您有机会删除过期的缓存。

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

      【讨论】:

      • 我注意到,附加标题的另一种解决方案(我首先尝试但因尝试手动复制 Response 对象的想法而推迟)具有以下好处还允许您的主应用检测何时提供这些缓存响应之一。
      猜你喜欢
      • 2012-08-19
      • 1970-01-01
      • 2022-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-24
      • 1970-01-01
      • 2019-12-01
      相关资源
      最近更新 更多