服务工作者和透明缓存更新

时间:2015-11-08 04:25:54

标签: service-worker

我正在尝试为一个简单但旧的Django Web应用程序安装ServiceWorker。我开始使用示例read-through caching example from the Chrome team

这很好但但并不理想,因为我想在需要时更新缓存。基于此处阅读所有其他服务工作者答案,有两种建议的方法。

  1. 使用某些服务器端逻辑来了解您显示的内容何时更新,然后更新您的服务工作者以更改预先缓存的内容。例如,这就是sw-precache所做的事情。

  2. 只要您依赖更新的资源,只需更新服务工作者JS文件中的缓存版本(请参阅上面缓存示例中的JS文件中的注释)。

  3. 对我来说,两者都不是很好的解决方案。首先,这是一个愚蠢的遗留应用程序。我没有sw-precache所依赖的应用程序堆栈。其次,其他人更新将要显示的数据(它基本上是带有详细信息页面的事物列表)。

    我想试试Jake Archibald在offline cookbook中提出的“使用缓存,但是从网络更新缓存”,但我无法让它发挥作用。

    我最初的想法是,我应该能够在我的服务工作者中返回缓存版本,但是如果网络可用,则会对将更新缓存的函数进行排队。例如,fetch事件监听器中的类似内容

    // If there is an entry in cache, return it after queueing an update
    console.log(' Found response in cache:', response);
    setTimeout(function(request, cache){
        fetch(request).then(function(response){
            if (response.status < 400 && response.type == 'basic') {
                console.log("putting a new response into cache");
                cache.put(request, response);
            }   
        })  
    },10, request.clone(), cache);
    
    return response;
    

    但这不起作用。页面卡住了加载。

    上面的代码有什么问题?什么是正确的方式来达到我的目标设计?

2 个答案:

答案 0 :(得分:5)

听起来https://jakearchibald.com/2014/offline-cookbook/#stale-while-revalidate非常接近你正在寻找的东西

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.open('mysite-dynamic').then(function(cache) {
      return cache.match(event.request).then(function(response) {
        var fetchPromise = fetch(event.request).then(function(networkResponse) {
          // if we got a response from the cache, update the cache
          if (response) {
            cache.put(event.request, networkResponse.clone());
          }
          return networkResponse;
        });

        // respond from the cache, or the network
        return response || fetchPromise;
      });
    })
  );
});

答案 1 :(得分:0)

在页面重新加载时,您可以使用新版本刷新服务工作者,同时旧版本将负责处理请求。

一切都完成后,没有页面使用旧的服务工作者,它将使用更新版本的服务工作者。

this.addEventListener('fetch', function(event){
    event.responseWith(
        caches.match(event.request).then(function(response){
            return response || fetch(event.request).then(function(resp){
                return caches.open('v1').then(function(cache){
                    cache.put(event.request, resp.clone());
                    return resp;
                })
            }).catch(function() {
                return caches.match('/sw/images/myLittleVader.jpg');
            });
        })
    )
});

我建议您通过以下链接查看详细功能

https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers