当前位置: 首页 > 知识库问答 >
问题:

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

慕容星晖
2023-03-14

当我更新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);
                }
            }));
        })
    );
});

共有3个答案

常业
2023-03-14

我在这里回答了一个类似的问题:https://stackoverflow.com/a/64880568/7626299

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

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

const req = new Request(url, { cache: 'reload' });

这里有更多细节。

有玄天
2023-03-14

当我需要清除所有旧的Service Worker和Service Worker缓存时,我将这个自毁Service Worker放在手边。

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

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)))

});

进一步阅读:

  • https://medium.com/@nekrtemplar/自毁-serviceworker-73d62921d717
  • https://github.com/NekR/self-destroying-sw/blob/master/tests/service-worker/www_fixed/sw.js
聂建茗
2023-03-14

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

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

return cache.addAll([
                "/".
                "/stylesheet.css",
                ...
            ]);

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

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

为了完全理解这里的主题,我建议您阅读这篇博客文章“缓存最佳实践”

 类似资料:
  • 我有以下问题。我有EditText和TextWatcher,它们根据一些规则格式化输入文本。在TextChanged()之后的方法中,我格式化它。然后我有格式化的字符串,我想用格式化的值替换EditText的旧值。接下来我们有两个选项: < li >使用EditText.setText() < li >使用Editable.replace() 如果我们使用第一个选项,EditText的工作速度非常

  • 一、简介 当对PHPSSO进行修改后,执行此操作。 二、功能演示 更新应用列表缓存。如下图所示:

  • 一、本功能说明 本节仅为更新缓存的作用,进行过某些模块的设置等操作或者感觉某些地方不正常的时候请更新缓存。 1).如何进入本功能 导航栏 选择扩展 -> 菜单栏 选择更新全站缓存

  • 我调用服务器数据通过使用ajax在index.html.它是完美的获取这些数据。现在,我正在和服务人员一起工作。我可以缓存所有的静态资产(图像,js,css),并在Chrome开发工具的应用程序选项卡中的缓存存储中检查这些缓存的资产。我可以在网络选项卡中看到这些资产也被缓存(磁盘缓存)。 现在,我想使用ServiceWorker缓存这些ajax响应(图像文件数组)。在“网络”选项卡中,我可以看到它

  • 我在使用Azure云服务时遇到了瓶颈问题。该服务过去工作正常,基本上它所做的就是将Azure存储帐户中的信息存储到Azure数据库中。上个月没有数据加载到Azure数据库中,服务有一段时间没有更改,数据库没有锁定问题,但当我尝试检查我的存储帐户时,它在新的Azure门户中不可用,但在旧门户中不可用,从旧门户我没有与新门户相同的选项。指标是可以的,但是我遇到的这个瓶颈问题,数据加载可能与新门户中丢失