I am working on a PWA, and I want to purge the cache completely every time I update the service worker. I have tried several strategies, but every time I delete a cache I can see items in the new cache with a timestamp older than the time of its creation.
我正在处理一个PWA,我想在每次更新服务工作线程时完全清除缓存。我尝试了几种策略,但每次删除缓存时,我都会看到新缓存中的项目的时间戳比其创建时间更早。
For example, if I create a new cache at 14:00:00
, I can see items with e.g. 14:00:02
timestamps, but also see items with e.g. 08:15:26
timestamps, which is way earlier than the time I even created the cache.
例如,如果我在14:00:00创建新缓存,我可以看到带有14:00:02时间戳的项目,但也可以看到带有08:15:26时间戳的项目,这比我创建缓存的时间要早得多。
I have found the same question on SO multiple times, but there were no answers, so I post it again. Maybe it will catch someone's attention.
我在很多次上都找到了同样的问题,但没有答案,所以我又发了一次。也许它会引起某些人的注意。
Strategy #1: Deleting the entire cache by its name then recaching
策略1:按名称删除整个缓存,然后重新缓存
self.addEventListener("install", (e) => {
e.waitUntil(caches.delete("appCache").then(() => {
caches.open("appCache").then((cache) => {
cache.addAll(stuffToCache);
});
}));
});
Strategy #2: Deleting cached items by their keys then recaching
策略2:按键删除缓存的项,然后重新缓存
self.addEventListener("install", (e) => {
e.waitUntil(caches.open("appCache").then((cache) => {
cache.keys().then((keys) => {
keys.forEach((request) => {
cache.delete(request);
});
}).finally(() => {
cache.addAll(stuffToCache);
});
}));
});
Strategy #3: Using versioned caches
策略3:使用版本化缓存
const date = new Date().toISOString();
self.addEventListener("install", (e) => {
e.waitUntil(caches.open(`appCache-${date}`).then((cache) => {
cache.addAll(stuffToCache);
}));
});
self.addEventListener("activate", (e) => {
e.waitUntil(caches.keys().then((keys) => {
keys.forEach((key) => {
if (key !== `appCache-${date}`) {
caches.delete(key);
}
});
}));
});
With all 3 strategies I use a network first dynamic caching. (<CACHE NAME>
is appCache
or appCache-${version.date}
, depending on the strategy.)
对于所有三种策略,我都使用网络优先的动态缓存。(<缓存名称>是AppCache还是AppCache-${version.date},具体取决于策略。)
self.addEventListener("fetch", (e) => {
e.respondWith(caches.open(<CACHE NAME>).then((cache) => {
return fetch(e.request).then((response) => {
cache.put(e.request, response.clone());
return response;
});
}));
});
What the heck am I doing wrong?
我到底做错了什么?
更多回答
can you check if this method is working for you? It's working for me. It uses version. Filter out old cache keys and then delete them.
你能检查一下这个方法对你是否有效吗?这对我很管用。它使用版本。过滤掉旧的缓存键,然后删除它们。
// cleanup old caches except precache
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheKeys => {
const oldKeys = cacheKeys.filter(key =>
key.indexOf(<CACHE_NAME>) === -1 && key.indexOf(version) === -1,
);
const deletePromises = oldKeys.map(oldKey => caches.delete(oldKey));
return Promise.all(deletePromises);
}),
);
});
更多回答
How does it differ from my solution in terms of seemingly keeping old chached values? My strategy #3 also deletes caches with old versions, but in the newly created cache there are old items.
它与我的解决方案有什么不同,因为它似乎保留了陈旧的价值观?我的策略3也删除了旧版本的缓存,但在新创建的缓存中有旧项。
the old items may be precache items that's why I mentioned that my method will delete the cache but not the items that are preached during load.
旧的项可能是预缓存项,这就是为什么我提到我的方法将删除缓存,但不会删除加载期间宣扬的项。
My app uses a single cache and I want to delete the whole content, not just certain items.
我的应用程序使用单一缓存,我想删除整个内容,而不仅仅是某些项目。
我是一名优秀的程序员,十分优秀!