javascript - 如何使用 url 删除 Service Worker 缓存

标签 javascript service-worker service-worker-events

我有一个从互联网上获得的服务工作线程文件 (sw.js):

const PRECACHE = 'precache-v1.1';
const RUNTIME = 'runtime';

// A list of local resources we always want to be cached.
const PRECACHE_URLS = [

  /* index page */
  'index.html', './',

  /* stylesheets */
  './assets/css/bootstrap.min.css', './assets/css/style.css', 

  /* javascripts */
  './assets/js/scripts.js', 

  /* images */
  './assets/images/logo.png'

];

// The install handler takes care of precaching the resources we always need.
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(PRECACHE)
      .then(cache => cache.addAll(PRECACHE_URLS))
      .then(self.skipWaiting())
  );
});

// The activate handler takes care of cleaning up old caches.
self.addEventListener('activate', event => {
  const currentCaches = [PRECACHE, RUNTIME];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
    }).then(cachesToDelete => {
      return Promise.all(cachesToDelete.map(cacheToDelete => {
        return caches.delete(cacheToDelete);
      }));
    }).then(() => self.clients.claim())
  );
});

// The fetch handler serves responses for same-origin resources from a cache.
// If no response is found, it populates the runtime cache with the response
// from the network before returning it to the page.
self.addEventListener('fetch', event => {
  // Skip cross-origin requests, like those for Google Analytics.
  if (event.request.url.startsWith(self.location.origin)) {
    event.respondWith(
      caches.match(event.request).then(cachedResponse => {
        if (cachedResponse) {
          return cachedResponse;
        }

        return caches.open(RUNTIME).then(cache => {
          return fetch(event.request).then(response => {
            // Put a copy of the response in the runtime cache.
            return cache.put(event.request, response.clone()).then(() => {
              return response;
            });
          });
        });
      })
    );
  }
});

在我网站的每个页面上,例如 index.htmlabout.htmlcontact.html,我都有以下代码:

if('serviceWorker' in navigator) { navigator.serviceWorker.register('sw.js'); }

我在每个页面上都有此代码的原因是因为我的网站上有很多页面,并且我希望浏览器在用户登陆我网站的任何页面时缓存所有文件。

例如,当用户访问 about.html 时,服务工作线程会缓存 sw.js 中列出的所有文件,并且还会缓存当前页面,即使它是未在 sw.js 中列出。这正是我想要的,因为我的网站上有数百个页面,并且我不想在 sw.js 文件中手动列出所有页面。问题是,当我更新 sw.js 中的版本号时,浏览器会删除 sw.js 中列出的所有旧缓存并重新缓存文件再说一遍,除了 about.html。每当用户再次访问此页面时,旧的 about.html 就会显示,所有其他文件都是新的。

如何克服这个问题?我想完全删除我的网站缓存的所有文件,而不仅仅是 sw.js 中列出的文件,并且由于 about.html 未列出,因此该缓存页面不会'没有更新。

最佳答案

问题是您的 about.html 文件保存在名为 runtime 的缓存中,该缓存没有版本控制。因此,即使您部署了一个带有增量 PRECACHE 缓存的新 sw.js,该缓存仍然是相同的。 (例如 precache-v1.2)

解决方案是将版本控制添加到运行时缓存中:

const PRECACHE = 'precache-v1.1';
const RUNTIME = 'runtime-v1.1';

或者在激活时清理运行时缓存:

self.addEventListener('activate', event => {
// only PRECACHE (which is already the new version, setup on install event) should not be deleted.
const currentCaches = [PRECACHE];
...

关于javascript - 如何使用 url 删除 Service Worker 缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55505662/

相关文章:

javascript - 我应该在哪里接受 Firefox 附加组件分发协议(protocol)?

javascript - 在 Angularjs 中访问模板内的属性值

javascript - 如何计算4个点的加权中心点?

javascript - 用 fetch 事件替换 service worker 中的 Assets

javascript - Service Worker 仅显示第一个推送通知(来自云消息传递),直到我重新加载 - 工作人员收到消息

javascript - 获取事件未收到请求 header

javascript - 使用 JavaScript 验证注册

javascript - 当应用程序处于 sleep 模式时,有没有办法在 PWA 中的服务工作人员中跟踪用户当前位置?

javascript - 如何从 Service Worker 对象调用 React 类的函数?

javascript - serviceWorker 'activate' 和 'message' 事件未触发