Service Worker skipWaiting 无法激活当前等待的软件 [英] Service Worker skipWaiting unable to activate currently waiting SW

查看:74
本文介绍了Service Worker skipWaiting 无法激活当前等待的软件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说明:

我们使用 sw precache 预先缓存脚本,因此为了更新脚本,我们提供了重新加载选项,为此,我们正在侦听工作人员消息以跳过等待新安装的服务工作人员,原因不明,我们没有得到正确的

We are using sw precache for caching the scripts before hand, hence to update the scripts we are giving reload option, for that we are listening the worker message to skip waiting the newly install service worker for unknown reason we are not getting correct

importScript

// GETTING OLD SW reference (self) and NOT getting newly installed SW reference

self.addEventListener('message', function(event) {
    *// not working*
    self.skipWaiting();
});



// But if we put skipWaiting() in 'install' listener 
// it is getting correct new SW reference and working correctly

self.addEventListener('install', function(event) {
    // self.skipWaiting();
});

软件注册

if('serviceWorker' in window.navigator) {
      window.addEventListener('load', function() {
        window.navigator.serviceWorker.register("/serviceWorker.js").then(function(registration) {
          console.log("ServiceWorker registration successful with scope: ", registration);
          registration.onupdatefound = function() {
            console.log('NEW WILD WORKER HAS SPAWNED.!', registration);
            var installedWorker = registration.installing;
            installedWorker.onstatechange = function() {
              if (installedWorker.state === 'installed') {
                if (navigator.serviceWorker.controller) {
                  console.log('Updated content is available RELOAD!', navigator.serviceWorker.controller);
                  var el = document.getElementById('feature');
                  el.style['display'] = 'block';
                }
              }
            }
          }
        }).catch(function(error) {
          console.error("ServiceWorker registration failed: ", error);
        });
      });
      window.navigator.serviceWorker.addEventListener('controllerchange', function() {
        console.log('SERVICE WORKER UPDATED');
      });
    }

webpack 配置

new SWPrecacheWebpackPlugin({
        cacheId: 'pwa',
        filename: 'serviceWorker.js',
        staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/, /_nch\.[0-9a-z]+\.[js, css]+/g, /webpackManifest\.[0-9a-z]+\.js/g, /.DS_Store\.[0-9a-z]+/g],
        importScripts: ['offline/offline.1a2b3c4df1.js'],
        dontCacheBustUrlsMatching: /./,
        minify: false,
        skipWaiting: false,
        runtimeCaching: [ {
          urlPattern: /_nch\.[0-9a-z]+\.[js, css]+/g,
          handler: 'fastest',
          options: {
            cache: {
              name: 'jd-internal-script',
              maxEntries: 10,
            },
          },
        }, {
          urlPattern: /webpackManifest\.[0-9a-z]+\.js/g,
          handler: 'networkFirst',
          options: {
            cache: {
              name: 'jd-root-doc',
            },
          },
        }],
      }),

推荐答案

skipWaiting() 的最佳文档可以在 https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle#skip_the_waiting_phase

您可以在 install 处理程序中无条件地调用它,也可以遵循您似乎正在做的模型,即侦听 message 事件并调用 skipWaiting() 有条件地.

You can either call it unconditionally in the install handler, or follow the model that you seem to be doing, which is to listen for a message event and call skipWaiting() conditionally.

如果你走条件路线,那么你应该修改你的客户端页面的代码,以正确检测你注册的 Service Worker 何时进入 waiting 状态,并为用户提供与之交互的选项页面的方式导致相应的 postMessage() 告诉服务工作者 skipWaiting().根据您所说的,您已经尝试过此操作,但您似乎将消息发送到了错误的 Service Worker 实例.

If you go the conditional route, then you should modify your client page's code to properly detect when the service worker you're registering enters the waiting state, and give the user the option of interacting with the page in a way that results in a corresponding postMessage() to tell the service worker to skipWaiting(). Based on what you're saying, you've tried this, but it looks like you're sending the message to the wrong service worker instance.

您的页面代码应如下所示:

Here's what you page's code should look like:

// On your page:
if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('service-worker.js').then(function(reg) {
      reg.onupdatefound = function() {
        var newSW = reg.installing;
        newSW.onstatechange = function() {
          if (newSW.state === 'waiting') {
            // This assumes there's a button with id='skip-waiting-button' that
            // users should click to get the new SW to activate immediately.
            var button = document.querySelector('#skip-waiting-button');
            button.addEventListener('click', function() {
              newSW.postMessage('skipWaiting');
            });
            // Assume that 'display' is 'none' initially.
            button.style.display = 'inline';
          }
          // Handle whatever other SW states you care about, like 'active'.
        };
      };
    })
  });
}

// In your service worker:
self.addEventListener('message', event => {
  if (event.data === 'skipWaiting') {
    self.skipWaiting();
  }
});

这篇关于Service Worker skipWaiting 无法激活当前等待的软件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆