Javascript Service Worker更新,但仍缓存旧文件

Javascript Service Worker更新,但仍缓存旧文件,javascript,service-worker,Javascript,Service Worker,当我更新service worker时,我关闭并重新打开该页面,并获得控制台日志,表明新的service worker已安装并激活,旧的缓存已删除。但是,列出要添加到缓存中的文件不会再次从服务器获取,它们是数小时前的旧版本。除了清除Chrome开发工具中的存储之外,没有办法让它更新文件 安装新版本时,如何让我的服务人员使用新文件填充其缓存 例如,当服务人员更新时,“stylesheet.css”仍然是旧版本: let cacheName = "abc_web_v1_15"; self.addE

当我更新service worker时,我关闭并重新打开该页面,并获得控制台日志,表明新的service worker已安装并激活,旧的缓存已删除。但是,列出要添加到缓存中的文件不会再次从服务器获取,它们是数小时前的旧版本。除了清除Chrome开发工具中的存储之外,没有办法让它更新文件

安装新版本时,如何让我的服务人员使用新文件填充其缓存

例如,当服务人员更新时,“stylesheet.css”仍然是旧版本:

let cacheName = "abc_web_v1_15";

self.addEventListener('install', (event) => {
    console.log('[Service Worker] Install');
    event.waitUntil(
        caches.open(cacheName).then(function (cache) {
            return cache.addAll([
                "/".
                "/stylesheet.css",
                ...
            ]);
        })
    );
});
self.addEventListener('fetch', (e) => {
    e.respondWith(
        caches.match(e.request).then(function (r) {
            console.log('[Service Worker] Fetching resource: ' + cacheName + ' ' + e.request.url);
            if (r) {
                console.log(cacheName + ' returning cached  ' + e.request);
                return r;
            } else {
                console.log(cacheName + ' returning fetched  ' + e.request);
                return fetch(e.request);
            }
        })
    )
});

self.addEventListener('activate', (e) => {
    console.log('[Service Worker] Activate');
    e.waitUntil(
        caches.keys().then((keyList) => {
            return Promise.all(keyList.map((key) => {
                if (cacheName.indexOf(key) === -1) {
                    console.log(`[Service Worker] Removing Cached Files from Cach-${key}`);
                    return caches.delete(key);
                }
            }));
        })
    );
});
当我需要清除所有旧的服务人员和服务人员缓存时,我将这个自毁的服务人员放在手边

我发现它是一个非常有用的工具

self.addEventListener('install', event => self.skipWaiting());

self.addEventListener('activate', event => {

  // Delete all Service Worker Caches
  caches.keys().then(cacheNames => {for (let name of cacheNames) {caches.delete(name);}});

  // Unregister all Service Workers
  self.registration.unregister()

    .then(() => self.clients.matchAll())

    .then((clients) => clients.forEach(client => client.navigate(client.url)))

});

进一步阅读:


问题很简单:当服务人员请求“新”文件时,
fetch
请求通过常规浏览器HTTP缓存。如果在那里找到资源,浏览器会自动返回该资源,而不会进入网络

如果查看代码中的此代码段:

return cache.addAll([
                "/".
                "/stylesheet.css",
                ...
            ]);
您将看到,无论内容如何,样式表的名称总是相同的。换句话说,当样式表更新时,文件名仍然相同。由于这个原因,该文件已经在浏览器的HTTP缓存中,因此SW会在请求时获取该文件

你应该更新你的文件。通常使用文件内容的散列。使用散列命名,您最终会得到类似于
样式表.iudfirio132.css的名称,并且每当文件更改一个字符时,该名称都会更改。这样,应用程序的新版本总是使用不同名称的资源。您还应该使用诸如Workbox precaching之类的构建工具来更新服务工作者文件中的资源列表,这样您就不需要手动执行。更多:


要完全理解这里的主题,我建议您阅读这篇博客文章“缓存最佳实践和最大年龄陷阱”

我在这里回答了一个类似的问题:

正如pate所提到的,即使您正在用新代码、新缓存名称更新服务人员,调用
self.skipWaiting()
,他仍然在缓存中放入缓存中的旧资源

实际上,你可以重写你的安装事件处理程序并去掉
缓存.addAll
。要解决此问题,您需要通过将
缓存
选项设置为
重新加载
来获取每个资源,这样浏览器将使用网络获取资源,而不是缓存

const req=新请求(url,{cache:'reload'});

.

我在这里回答了一个类似的问题,我希望它能帮助您:我在这里回答了一个类似的问题,我希望它能帮助您: