我正在创建一个需要脱机支持和更新的Web应用程序。当我更新应用程序时,新的服务工作者开始从磁盘缓存中缓存文件,并且不更新应用程序。这将导致新的缓存获取旧文件。 Screenshot of chrome network debbuging。
const STATICCACHE = 'v9';
const DYNCACHE = 'dv2';
//v9
const assets = [
// All my assets
];
// install
self.addEventListener('install', event => {
event.waitUntil(
caches.open(STATICCACHE).then(cache => {
console.log("caching assets");
cache.addAll(assets);
})
);
});
// activate event
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys => {
return Promise.all(keys
.filter(key => key !== STATICCACHE && key !== DYNCACHE)
.map(key => caches.delete(key))
)
})
)
});
//fetch event
self.addEventListener('fetch', event => {
if (event.request.url.indexOf('firestore.googleapis.com') === -1) {
event.respondWith(
caches.match(event.request).then(cacheRes => {
return cacheRes || fetch(event.request).then(fetchRes => {
return caches.open(DYNCACHE).then(cache => {
cache.put(event.request.url, fetchRes.clone());
return fetchRes;
})
});
})
);
}
});
在适用于Android的chrome浏览器和iOS上的Safari浏览器中,该功能也无法正常工作。
感谢您的帮助
答案 0 :(得分:0)
之所以会发生这种情况,是因为资产的名称在更新时不会更改,例如。无论文件内容如何,app.js始终都是app.js。从浏览器的角度来看,文件没有更改。
您可以通过以下两种主要方法进行处理:
确保您的服务器对所有静态资产使用正确的HTTP标头,例如。 ETag或缓存:过期验证等。通过这种方式,即使资产名称没有更改,您也可以强制浏览器检查服务器的新版本。
以任何方式更改文件时,始终更改它们的名称。
第二个选项是大多数人在开发Web应用程序时使用的内容。通常,工具,JS捆绑器等确保文件名更改。文件名通常分为两部分,包括文件内容的哈希值:例如app.8927349789adf8.js
和styles.329789dfs89sigjg.css
。当然,您不想手动执行此操作,而是使用Webpack或Parcel等之类的方法。
您还可以使用一些解决方法,例如使浏览器请求。 app.js?XXXXXX
,其中XXXXX是当前时间或类似的时间。此外,如果您要合并某些Service Worker库(如Workbox),则即使名称保持不变,它也支持跟踪文件内容的更改。基本上,Workbox会计算文件的哈希值,然后使用查询参数技巧将其缓存。 styles.css?_HASH_OF_THE_FILE
。您也可以将这种技巧结合到手写的SW文件中-当缓存名称更改时,只需从服务器请求文件,然后在所有请求中附加?current_time
之类的内容即可。这将迫使浏览器执行网络请求。