Javascript 如何在服务人员更新后硬刷新Firefox?

Javascript 如何在服务人员更新后硬刷新Firefox?,javascript,firefox,service-worker,workbox,Javascript,Firefox,Service Worker,Workbox,我已经实现了下面的代码来清除服务工作者缓存并重新加载-在用户接受服务工作者的更新之后。该代码在Chrome和Edge中运行良好,但Firefox不会重新加载页面。Firefox会一直要求安装相同的版本,直到我硬刷新(shift-reload)页面 service-worker-base.js // Imports const CACHE_DYNAMIC_NAME = 'DEBUG-035' setCacheNameDetails({ prefix: 'myApp', suffix: CACH

我已经实现了下面的代码来清除服务工作者缓存并重新加载-在用户接受服务工作者的更新之后。该代码在Chrome和Edge中运行良好,但Firefox不会重新加载页面。Firefox会一直要求安装相同的版本,直到我硬刷新(shift-reload)页面

service-worker-base.js

// Imports

const CACHE_DYNAMIC_NAME = 'DEBUG-035'

setCacheNameDetails({ prefix: 'myApp', suffix: CACHE_DYNAMIC_NAME });

// Cache then network for css
registerRoute(
  '/dist/main.css',
  new StaleWhileRevalidate({
    cacheName: `${CACHE_DYNAMIC_NAME}-css`,
    plugins: [
      new ExpirationPlugin({
        maxEntries: 10, // Only cache 10 requests.
        maxAgeSeconds: 60 * 60 * 24 * 7 // Only cache requests for 7 days
      })
    ]
  })
)

// Cache then network for images
//...

// Use a stale-while-revalidate strategy for all other requests.
setDefaultHandler(new StaleWhileRevalidate())

precacheAndRoute(self.__WB_MANIFEST)

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

// Clear cache before installing new service worker
self.addEventListener('activate', (event) => {
  var cachesToKeep = ['none'];
  event.waitUntil(
    caches.keys().then((keyList) => {
      return Promise.all(keyList.map((key) => {
        if (cachesToKeep.indexOf(key) === -1) {
          console.log('Delete cache', key)
          return caches.delete(key);
        }
      }));
    })
  );

  event.waitUntil(self.clients.claim());
});

//...
app.js

const enableServiceWorker = process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'qa'
const serviceWorkerAvailable = ('serviceWorker' in navigator) ? true : false
if (enableServiceWorker && serviceWorkerAvailable) {

  const wb = new Workbox('/service-worker.js');
  let registration;

  const showSkipWaitingPrompt = (event) => {
    if (window.confirm("New version available! Refresh?")) {
      wb.addEventListener('controlling', (event) => {
        window.location.reload();
      });

      console.log('registration', registration) //<-- LINE 13 
      // In Chrome and Edge this logs a service worker registration object
      // In Firefox, this is undefined !!? 

      if (registration && registration.waiting) {
        messageSW(registration.waiting, {type: 'SKIP_WAITING'});
      }
    }
  }

  // Add an event listener to detect when the registered service worker has installed but is waiting to activate.
  wb.addEventListener('waiting', showSkipWaitingPrompt);
  wb.addEventListener('externalwaiting', showSkipWaitingPrompt);

  wb.register().then((r) => {
    registration = r
    console.log('Service worker registered', registration) //<-- LINE 23
  }).catch(registrationError => {
    console.error('Service worker error', registrationError )
  })
}

// Install prompt event handler
export let deferredPrompt
window.addEventListener('beforeinstallprompt', (event) => {
  event.preventDefault() // Prevent Chrome 76 and later from showing the mini-infobar
  deferredPrompt = event // Stash the event so it can be triggered later.
 
  // Update UI notify the user they can add to home screen
  try{
    showInstallPromotion()
  }catch(e){
    // console.log('showInstallPromotion()', e)
  }
})
window.addEventListener('appinstalled', (event) => {
  console.log('a2hs installed')
})
火狐

registration undefined app.js:13:14
Service worker registered > ServiceWorkerRegistration { installing: null, waiting: ServiceWorker, active: ServiceWorker, scope: "http://127.0.0.1:8080/", updateViaCache: "imports", onupdatefound: null, pushManager: PushManager } app.js:23:12

亲切问候/K

这可能会对您有所帮助,请检查serviceworker的
控制器更改

根据文档:
ServiceWorkerContainer
接口的
oncontrollerchange
属性是一个事件处理程序,每当“controllerchange事件发生时”——当文档的关联ServiceWorkerRegistration获取一个新的活动工作程序时触发

要使用它,您可以附加一个事件处理程序,并且只有当新的服务工作者激活时才会触发它。如果需要,可以使用
reload
功能重新加载页面

navigator.serviceWorker.addEventListener('controllerchange', function(){
    window.location.reload();
});

我创建了一个特例,因为Firefox安装新的服务人员似乎与chromium不同(第13行没有服务人员注册的句柄)

当新服务人员正在等待时,将触发showSkipWaitingPrompt
,并

  • 在Chromium中,服务工作者注册就绪--->我们称之为SKIP_WAITING-->浏览器将重新加载并替换服务工作者
  • 在Firefox中,服务工作者注册句柄不可访问,但我们不能调用SKIP_WAITING
  • 对我来说,解决办法是在注册中添加下面的一行。这会告诉Firefox在新服务人员处于等待状态并且我们有注册句柄时跳过等待

     wb.register().then((r) => {
        registration = r
        if(registration.waiting){ mySkipWaitingNow() } // Fix for firefox
        ...
    
    mySkipWaitingNow()
    告诉服务人员跳过等待,而不提示用户

    这将不会在Chrome/Edge中触发,因为浏览器会在
    showSkipWaitingPrompt()
    中重新加载-请参见上文第1点

    为了防止可能的永久循环,我还创建了一个全局变量
    skipwaitingconfirmind
    ,该变量在
    showSkipWaitingPrompt()
    中设置,并签入
    mySkipWaitingNow()


    /K

    嗨,维姆!谢谢你的回复!(^_^)/我尝试先在service-worker-base.js中实现“oncontrollerchange”,然后在app.js中实现。不幸的是,Firefox中没有触发此事件:-(问候/KCan你可以分享你的安装事件吗?是的,绝对可以!:-D我已经在上面的代码中添加了我的安装事件。/KHello Vimal!我已经添加了我所有的服务人员代码。我现在看到我没有安装事件处理程序。/KHi Vimal,谢谢你花时间!我已经通过在Firefox激活时捕获案例来解决了这个问题,但是我没有缺少“注册”句柄。将很快共享解决方案!/K
     wb.register().then((r) => {
        registration = r
        if(registration.waiting){ mySkipWaitingNow() } // Fix for firefox
        ...