Javascript 在移动设备上未触发服务工作程序`onupdatefound`

Javascript 在移动设备上未触发服务工作程序`onupdatefound`,javascript,android,google-chrome,service-worker,workbox,Javascript,Android,Google Chrome,Service Worker,Workbox,下面是我如何注册我的服务人员: if ('serviceWorker' in navigator) { window.addEventListener('load', () => { function updateOnlineStatus() { SnackBar.show({ text: navigator.onLine ? onlineMsg : offlineMsg, backgroundColor: '#000000',

下面是我如何注册我的服务人员:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    function updateOnlineStatus() {
      SnackBar.show({
        text: navigator.onLine ? onlineMsg : offlineMsg,
        backgroundColor: '#000000',
        actionText: close,
        actionTextColor: '#d2de2f',
        customClass: 'custom-snackbar',
      });
    }
    window.addEventListener('online', updateOnlineStatus);
    window.addEventListener('offline', updateOnlineStatus);
    navigator.serviceWorker.register('sw.js').then((reg) => {
      reg.onupdatefound = () => {
        const installingWorker = reg.installing;
        installingWorker.onstatechange = () => {
          switch (installingWorker.state) {
            case 'installed':
              if (navigator.serviceWorker.controller) {
                SnackBar.show({
                  text: refreshMsg,
                  backgroundColor: '#000000',
                  actionText: refresh,
                  actionTextColor: '#d2de2f',
                  onActionClick: () => { location.reload(); },
                  customClass: 'custom-snackbar',
                });
              } else {
                console.info(availableMsg);
              }
              break;
            case 'redundant':
              console.info(redundantMsg);
              break;
            default:
              break;
          }
        };
      };
    }).catch((e) => {
      console.error(errorMsg, e);
    });
  });
}
此服务辅助程序是在按Workbox生成期间生成的

我有点担心,因为这些通知显示在我的电脑上(ubuntu++
chrome 59.0.3071.115
),但从来没有在我的手机上显示过(android 6.0.1++
chrome 59.0.3071.125

使用远程调试功能进行分析后,我的手机上似乎从未触发过
onupdatefound

我对UX感觉很糟糕,想到手机上的访问者不知道新版本的网站即将发布

如有任何建议,将不胜感激


编辑1:我找到了有关此网页“浏览器兼容性”部分的更多详细信息:。Chrome对Android的支持似乎是未知的

当浏览器不支持
onupdatefound
事件时,你们是否有一种回退/解决方法


编辑2:回应Jeff,
sw.js
头在
.htaccess
文件中管理:

<Files sw.js>
  Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
  Header set Pragma "no-cache"
  Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</Files>
关于您建议的workbox微调,我还没有来得及深入研究,所以我在一个文件中使用了easy
workbox build
。但我希望会:)

你认为这可能是由skipWaiting:true引起的吗


编辑3:尝试使用广播频道

navigator.serviceWorker.register('/sw.js').then((reg) => {
  console.log('test');
  const updateChannel = new BroadcastChannel('precache-updates');
  updateChannel.addEventListener('message', event => {
    console.log(`Cache updated: ${event.data.payload.updatedUrl}`);
  });
}).catch((e) => {
  console.error(errorMsg, e);
});

即使在Chrome、mobile或firefox的日志中输出了
test
,更新消息只在Chrome上抛出

在Android和Linux上Chrome的service worker实现中应该没有任何区别,这将解释一个平台在service worker注册时没有暴露
updatefound
事件。(MDN在这里不一定具有权威性。)

过去,每当我调试这种不可预测的更新时,都是由于与HTTP缓存和
sw.js
脚本的交互。你能检查一下你在提供
sw.js
服务时使用的
缓存控制
头吗


另外,您提到您正在使用Workbox,如果是这样的话,您可以使用更高级的方法来检查更新的资源。
workbox broadcast cache update
插件(如果您使用的是
workbox sw
precache()
方法,则默认情况下会启用该插件)可以宣布特定缓存资源何时更新,然后您可以使用广播频道API在页面上侦听该消息。这样,当最重要的资源(如HTML)发生变化时,您才可以显示您的
SnackBar
,而不是不太重要的资源(如可能预先制作的随机图像)。

正如您所怀疑的,问题根本不是服务人员自己造成的

我从零开始,试图找出这个问题的根源,逐段添加代码,直到没有更多的事件被暴露。我明白了:这是因为
three.js
动画中使用了一个“昂贵”的循环

在将这段代码放入worker之后,我的页面现在能够在移动设备或Firefox上捕获这些事件,用户的通知工作正常

关于它在桌面版Chrome上工作这一令人困惑的事实,我想这是因为它必须支持多线程


再次感谢您的帮助:)

您可能希望在查看文档后修改您的观察者。感谢您抽出时间!我编辑了OP,其中包含了与您的观察相关的更多详细信息
skipWaiting
clientsClaim
都不应阻止触发
updatefound
事件。如果您使用的是
workbox build
,那么生成的
sw.js
将“免费”获得广播频道API更新。只需在
precache updates
频道上收听客户端页面的更新。见我应用了你的建议(编辑3)。遗憾的是,它在手机或Firefox上仍然不起作用,但在PC的chrome上仍然起作用。我真的很困惑:(但无论如何还是要感谢你的帮助!这似乎是一个bug。你向chromium团队报告了吗?
// Service Worker generation
gulp.task('bundle-sw', gulp.series('generate-sitemap', () => {
  return wbBuild.generateSW({
    globDirectory: gulpOutputDir,
    swDest: `${gulpOutputDir}/sw.js`,
    globPatterns: ['**/*.{html,png,xml,css,ico,txt,json,svg,js,map,gif,jpeg,jpg,bmp,cur,webp,woff2}'],
    skipWaiting: true,
    clientsClaim: true,
  })
  .then(() => {
    console.warn('Service worker generated.');
  })
  .catch((err) => {
    console.error(`[ERROR] This happened: ${err}`);
  });
}));
navigator.serviceWorker.register('/sw.js').then((reg) => {
  console.log('test');
  const updateChannel = new BroadcastChannel('precache-updates');
  updateChannel.addEventListener('message', event => {
    console.log(`Cache updated: ${event.data.payload.updatedUrl}`);
  });
}).catch((e) => {
  console.error(errorMsg, e);
});