如何由服务工作者更新缓存的资源

谢兰德拉·沙玛(Shailendra Sharma)

我有一个基于Service Worker的离线应用程序,它允许用户离线下载pdf文件。

有一个文本文件,具有特定格式的pdf文件的下载路径和文件标题(以及css,js和images路径),Application通过ajax读取此文本文件并绘制所有可用pdf文件的列表(通过显示标题和下载链接)

在安装过程中,Worker会读取相同的文件,并将所有pdf文件以及文本文件本身放入缓存中,以便可以脱机使用这些文件。

当我用一些新的pdf文件更新文本文件时,会出现问题,因为该应用程序向文件提供了ajax请求,并且工作程序能够通过fetch事件更新它,因此工作程序能够在缓存中更新更新的文本文件,但是新添加的PDF文件未作为未触发获取而添加到缓存中。

// function to register worker add files in the cache 
this.addEventListener('install', event => {
    const client = clients.get(event.clientId);
    fetch('masterdata.txt')
        .then(
            function(response) {
                response.text().then(function(text) {
                    var documentFileArray = parseString(text);
                    var cacheDocs = [];
                     clients.claim();
                    var  count = 0;
                     caches.open(currentCache.offline).then(function(cache) {
                         var total_files = documentFileArray.length;
                         for(var i =0;i<total_files;i++){                            
                             cache.add(documentFileArray[i]).then(function(){   
                                 count++
                                 var data = {'count':count,'total':total_files}
                                 passMesagetoClient(clients,data)                            
                             })
                         }
                    })
                })
            }
        )
        .catch(function(err) {
            //console.log('Fetch Error :-S', err);
            clients.claim();
            passMesagetoClient(clients,'failed');
        });
});


//comman function to let client know service worker done caching files 
function passMesagetoClient(client,data){   
    client.matchAll().then(all => {
        all.map(client => {         
                client.postMessage({"status":"success","data":data})
            })
    }); 
}

//this will check and provide the files from cache if network not avalible 
this.addEventListener("fetch", function(event) {
    //var url = event.request.url;
       clients.claim();
       passMesagetoClient(clients,'success');
                        
        event.respondWith(
            fetch(event.request).then(function(response) {
                return caches.open(currentCache.offline).then(function(cache) {
                    return cache.put(event.request, response.clone()).then(function() {
                        return response
                    })
                })
            }).catch(function(e) {
                //console.log(e);
                return caches.match(event.request)
            })
        )
   
})

如果文本文件中有任何更新,是否有办法更新缓存中新添加的pdf文件?

艾哈迈德·莫赫塔尔(Ahmed Mokhtar)

这是一个简单的解决方案。fetch事件中,我检查,如果request是的masterdata.txt,如果是之前,我覆盖responsecache我得到的是旧masterdata.txtcache,如果它存在,我比较这两个检查,如果它们是不同的,这意味着有添加新的文件,然后我fetch的文件和将它们添加到中cache

// add the files in the array to the cache
async function cacheFiles(filesArray) {
  const count = 0;
  const cache = await caches.open(currentCache.offline);
  const totalFiles = filesArray.length;
  for (let i = 0; i < totalFiles; i++) {
    await cache.add(filesArray[i]);
    count++;
    const data = { count: count, total: totalFiles };
    passMesagetoClient(clients, data);
  }
}

// this will check and provide the files from cache if network not avalible
this.addEventListener("fetch", function(event) {
  clients.claim();
  passMesagetoClient(clients, "success");

  event.respondWith(
    fetch(event.request)
      .then(async function(newResponse) {
        // If this is the text file
        if (event.request.url.includes("masterdata.txt")) {
          // try to get the text file from the cache
          const cachedResponse = await caches.match(event.request);

          // If it exists
          if (cachedResponse) {
            // convert both responses to text
            const cachedText = await cachedResponse.text();
            const text = await newResponse.text();
            // if they are different
            if (cachedText !== text) {
              // If you can compare the old and new text to get the new urls
              // If you can't just compare the two arrays as following
              const oldFileArray = parseString(cachedText);
              const fileArray = parseString(text);
              // get the new urls
              const newFileArray = fileArray.filter(
                f => !oldFileArray.includes(f)
              );
              // fetch and cache them like you did in the install event
              await cacheFiles(newFileArray);
            }
          }
        }
        // add the new response to the cache
        const cache = await caches.open(currentCache.offline);
        cache.put(event.request, newResponse.clone());
        return newResponse;
      })
      .catch(function(e) {
        // console.log(e);
        return caches.match(event.request);
      })
  );
});

我有另一种解决方案,这取决于您如何更新masterdata.txt如果确实masterdata.txt要从客户端添加新文件的URL,则可以简单地同时获取和缓存。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

刷新时激活更新的服务工作者

如何卸载服务工作者?

Javascript服务工作者:从缓存中获取资源,但也进行更新

如何列出服务工作者已经存储在浏览器缓存中的博客帖子?

服务工作者和客户端请求“缓存控制”:“无缓存”

WebView:以编程方式清除服务工作者缓存

使用CSRF令牌缓存请求时,如何减少服务工作者缓存的大小

具有SSL证书缓存的服务工作者

PWA服务工作者缓存/更新预期行为

notificationclick事件服务工作者

根据年龄删除服务工作者缓存中的条目

注销时如何清除服务工作者缓存?

延迟加载或预加载Angular模块并使用服务工作者来缓存结果?

如何根据服务工作者中的某些标志缓存响应

如何在Google Devtools中强制更新服务工作者文件?

如何在服务工作者中刷新图片

在服务工作者中服务之前,可以编辑缓存的index.html吗?

通常,服务工作者应预缓存哪些文件?

从Create React App注册服务工作者时如何更新页面

PWA-服务工作者(反应)如何工作?

如何防止服务工作者删除缓存,PWA

服务工作者中的XMLHttpRequest

服务工作者,它是如何工作的?

如何使用服务工作者预缓存名称在每次部署时都会更改的资产?

服务工作者从磁盘缓存中缓存资源

服务工作者在反应中缓存的路由

服务工作者缓存与 VuexPersistence

角度缓存 - 我们应该使用服务工作者吗?

服务工作者缓存破坏谷歌地图 api