You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Service Worker自动下载新内容却不更新?如何在updated时自动刷新?

问题原因分析

首先,你遇到的这个问题核心在于Service Worker的生命周期机制:

  • 当你部署新代码后,浏览器会下载新的Service Worker文件,但此时旧的Service Worker仍在控制当前打开的页面,新的Service Worker会进入waiting状态,不会立即激活。这是浏览器的默认保护机制,避免正在运行的页面被突然更新打断,所以你会看到日志提示有新内容,但页面还是旧的。
  • 另一个可能的原因是你的缓存策略把index.html设置成了长期缓存,即使新内容已经下载,当前页面加载的还是缓存里的旧index.html,自然看不到更新后的内容。
自动刷新的实现方案

要在updated()钩子中实现自动刷新,我们需要让新的Service Worker跳过等待状态立即激活,然后通知页面刷新。具体步骤如下:

1. 修改Service Worker注册代码

更新你的注册逻辑,在updated钩子中发送消息让新的Service Worker跳过等待,同时监听控制器变化事件来刷新页面:

/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready() { console.log('App is being served from cache by a service worker.'); },
    registered() { console.log('Service worker has been registered.'); },
    cached() { console.log('Content has been cached for offline use.'); },
    updatefound() { console.log('New content is downloading.'); },
    updated(registration) {
      console.log('New content is available; preparing to refresh...');
      // 向等待中的Service Worker发送跳过等待的指令
      registration.waiting.postMessage({ type: 'SKIP_WAITING' });
      // 监听Service Worker控制器变化,刷新页面
      navigator.serviceWorker.addEventListener('controllerchange', () => {
        window.location.reload();
      });
    },
    offline() { console.log('No internet connection found. App is running in offline mode.'); },
    error(error) { console.error('Error during service worker registration:', error); }
  });
}

2. 在Service Worker中添加消息监听

需要在你的Service Worker文件(如果是Vue CLI生成的,通常是public/service-worker.js或者构建后生成的sw文件)中添加监听message事件的逻辑,处理跳过等待的指令:

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

3. 优化缓存策略(可选但重要)

为了确保index.html能及时获取到最新版本,建议在vue.config.js中调整Workbox的缓存策略,对index.html使用StaleWhileRevalidate策略(先返回缓存内容,同时后台请求最新版本更新缓存):

module.exports = {
  pwa: {
    workboxOptions: {
      runtimeCaching: [
        {
          urlPattern: /\/index\.html$/,
          handler: 'StaleWhileRevalidate',
          options: {
            cacheName: 'index-html-cache'
          }
        }
      ]
    }
  }
};

这样修改后,当有新内容部署时,浏览器会自动下载新的Service Worker,跳过等待状态激活,然后触发页面刷新,用户就能看到最新的内容了。

内容的提问来源于stack exchange,提问作者markzzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:37:44