我有一个基于service worker的离线应用程序,允许用户离线下载pdf文件。
有一个文本文件,其中包含pdf文件的下载路径和特定格式的文件标题(以及css、js和图像路径),应用程序通过ajax读取此文本文件并绘制所有可用pdf文件的列表(通过显示标题和下载链接)
在安装过程中,工作人员读取相同的文件,并将所有pdf文件与文本文件一起放入缓存中,以便这些文件可以离线访问。
当我用一些新的pdf文件更新文本文件时,就会出现这个问题,因为应用程序给文件一个ajax请求,所以工作人员能够在缓存中更新更新的文本文件,并且工作人员能够通过读取事件在缓存中更新它,但是新添加的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文件?
这里有一个简单的解决方案。在获取事件中,我检查请求
是否为masterdata.txt
,如果是,在覆盖缓存
中的响应
之前,我得到旧的<代码>masterdata.txt从缓存
,如果它存在,我会比较两者,以检查它们是否不同,这意味着有新的文件添加,然后我获取
这些文件并将它们添加到缓存
.
// 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);
})
);
});
我想到了另一个解决方案,这取决于如何更新主数据。txt
。如果您确实将新文件URL添加到主数据。txt
从客户端,您可以简单地同时获取和缓存。
我使用带有sw工具箱库的service worker。我的PWA缓存除API查询(图像、css、js、html)之外的所有内容。但是如果有一天某些文件会被更改呢。或者如果服务人员。js将被更改。应用程序应该如何知道文件中的更改? 我的服务人员。js: 我不知道在PWA中更新缓存的常用方法是什么。也许PWA应该在后台发送AJAX请求并检查UI版本?
我试图安装一个简单的ServiceWorker,但旧的,Django Web应用程序。我开始使用Chrome团队的示例读取缓存示例 这很好,但并不理想,因为如果需要,我想更新缓存。根据阅读此处所有其他服务人员的答案,有两种推荐方法。 > 使用一些服务器端逻辑来知道您显示的内容何时更新,然后更新您的服务辅助角色以更改所述内容。例如,这就是sw-preache所做的。 只要在需要更新资源时更新serv
因此,我有一个带有服务工作者的HTML页面,服务工作者缓存索引。html和我的JS文件。 问题是当我更改JS时,更改不会直接显示在客户端浏览器上。当然,在chrome开发工具中,我可以禁用缓存。但是在Chrome Mobile,我该怎么做呢? 我试图访问站点设置并点击CLEAR%RESET按钮。但它仍然从缓存加载旧页面/加载。我试图使用其他浏览器或铬隐姓埋名,它加载新的页面。 然后,我尝试清除我的
我使用sw-precache生成Polymer-CLI构建过程中的服务工作,因此它旨在更新更新文件的散列,以表示需要更新缓存。但是缓存中没有替换我更新的内容,因此如果我使用ctrl-r刷新,它将获得旧版本,但如果使用ctrl-shift-r刷新,它将获得新版本。原因可能是我的服务人员没有更新。 这份文件说 如果与当前相比,服务辅助程序文件中甚至有一个字节的差异,它就认为它是新的。 ,但如果我的新服
我将React应用程序转换为PWA,它的工作部分正常。 我遵循了本教程:https://medium.com/@toricpope/transform-a-react-app-to-a-progressive-web-app-pwa-dea336bd96e6 然而,本文只展示了如何缓存静态数据,我还需要存储来自服务器的数据,我可以按照本文第一个答案的说明来做:如何将API中的数据缓存到React
我读过的一些文章建议由ServiceWorker(WebCacheAPI)缓存的项永远存储在系统中。我遇到过这样一种情况,当用户在很长一段时间后重新访问我的网站时,一些缓存的资源会被自动收回(~ 如果是这种情况,那么浏览器如何决定它必须删除哪些资源?我是否可以告诉浏览器,如果它正在从缓存中删除某些内容,则删除使用相同缓存名称缓存的所有内容?