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

如何检测React PWA是否运行最新版本并正确设置localStorage更新标记

问题根因

你当前代码里localStorage.setItem("updateAvailable", "false")的逻辑仅在首次注册Service Worker的场景下才会触发——只有用户第一次访问PWA、本地没有运行过旧Service Worker时,才会进入navigator.serviceWorker.controller为空的分支执行赋值。当用户已经运行过Service Worker、当前就是最新版本时,registration.onupdatefound事件根本不会触发,自然不会执行设为false的逻辑,之前遗留的true标记就会一直存在。

正确实现方案

你需要补充三个场景的标记处理逻辑:

  • 页面初始化加载时先默认重置标记为false,避免旧标记残留
  • 注册Service Worker时先检查是否已有等待激活的新版本,有则标记为true
  • 监听Service Worker接管事件,新版本完成安装接管页面后自动重置标记为false

修改后参考代码:

// 页面初始化先重置更新标记,默认无可用更新
localStorage.setItem("updateAvailable", "false")

function registerValidSW(swUrl: string, config?: Config) {
  console.log("test 5")
  navigator.serviceWorker
    .register(swUrl)
    .then(registration => {
      // 注册时先检查是否已有等待激活的新版本SW,有则直接标记可更新
      if (registration.waiting) {
        localStorage.setItem("updateAvailable", "true")
        if (config && config.onUpdate) {
          config.onUpdate(registration);
        }
      }

      registration.onupdatefound = () => {
        const installingWorker = registration.installing;
        if (installingWorker == null) {
          return;
        }
        installingWorker.onstatechange = () => {
          if (installingWorker.state === 'installed') {
            if (navigator.serviceWorker.controller) {
              console.log(
                'New content is available and will be used when all ' +
                  'tabs for this page are closed.'
              );
              localStorage.setItem("updateAvailable", "true")

              if (config && config.onUpdate) {
                config.onUpdate(registration);
              }
            } else {
              console.log('Content is cached for offline use.');
              localStorage.setItem("updateAvailable", "false")

              if (config && config.onSuccess) {
                config.onSuccess(registration);
              }
            }
          }
        };
      };
    })
    .catch(error => {
      console.error('Error during service worker registration:', error);
    });
}

// 监听新SW接管页面事件,重置更新标记
navigator.serviceWorker.addEventListener('controllerchange', () => {
  localStorage.setItem("updateAvailable", "false")
  // 可选:如果需要更新完成后立即刷新页面启用新内容,可放开下面注释
  // window.location.reload()
});

补充说明

如果你做了手动立即更新的功能,比如用户点击更新按钮后调用registration.waiting?.postMessage({ type: 'SKIP_WAITING' })触发SW跳过等待,更新完成后也会自动触发上面的controllerchange事件,不需要额外处理标记重置逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:27:01