Javascript 即使在重新加载页面后也显示服务人员更新通知

Javascript 即使在重新加载页面后也显示服务人员更新通知,javascript,progressive-web-apps,service-worker,service-worker-events,Javascript,Progressive Web Apps,Service Worker,Service Worker Events,我使用这个众所周知的模式来显示服务工作者更新准备好安装时的通知(此代码进入网页,当然不是服务工作者代码): 当然,该代码是有效的,因为如果服务工作者的新版本已经准备好安装,它会在网页上显示一个通知 问题在于,如果此时重新加载页面,通知将不再显示,因为如果安装了新的service worker并等待激活,则不再触发updatefound事件 因此,当安装新的服务工作者并等待激活并开始控制页面时,通知只出现一次,但一旦页面重新加载,通知就消失了 我已经通过使用注释代码解决了这个问题: // The

我使用这个众所周知的模式来显示服务工作者更新准备好安装时的通知(此代码进入网页,当然不是服务工作者代码):

当然,该代码是有效的,因为如果服务工作者的新版本已经准备好安装,它会在网页上显示一个通知

问题在于,如果此时重新加载页面,通知将不再显示,因为如果安装了新的service worker并等待激活,则不再触发
updatefound
事件

因此,当安装新的服务工作者并等待激活并开始控制页面时,通知只出现一次,但一旦页面重新加载,通知就消失了

我已经通过使用注释代码解决了这个问题:

// The commented code below is needed to show the notification after a page reload.
//
// if (registration.waiting) {
//     console.log('Service working in skipwaiting state.');
//     showUpdateNotification();
// }
注册时,此代码检查是否有服务人员处于等待状态,并再次显示通知

我的问题是:这对吗?我能安全地使用那个“把戏”吗?还是我在自找麻烦

我是服务业的新手,所以我不确定我是否能做这种事情


事先非常感谢。

好吧,很抱歉自我回复,但我或多或少得到了我需要的东西,同时处理了所有的案例(至少是我的项目需要的所有案例)

我认为下面的代码或多或少涵盖了服务人员的整个生命周期的处理,可以用作这方面的非非常复杂的样板代码

我使用来自无数来源的信息设计了这段代码,包括StackOverflow、博客、来自其他PWA的代码等。不幸的是,我没有写下每一个信息源,因此对此我感到非常抱歉,我想说明我写了下面的代码,但我并没有发明它,我利用了别人的信息和智慧

非常感谢

if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {

        let refreshing = false;
        navigator.serviceWorker.addEventListener('controllerchange', () => {
            console.log('New service worker in charge.');
            if (refreshing) return;
            refreshing = true;
            window.location.reload();
        });

        navigator.serviceWorker.register('/sw.js').then(registration => {
            console.log('Service worker registered.');

            // No controller for this page, nothing to do for now.
            if (!navigator.serviceWorker.controller) {
                console.log('No service worker controlling this page.');
            }    

            // A new service worker has been fetched, watch for state changes.
            //
            // This event is fired EVERY TIME a service worker is fetched and
            // succesfully parsed and goes into 'installing' state. This
            // happens, too, the very first time the page is visited, the very
            // first time a service worker is fetched for this page, when the
            // page doesn't have a controller, but in that case there's no new
            // version available and the notification must not appear.
            //
            // So, if the page doesn't have a controller, no notification shown.
            registration.addEventListener('updatefound', function () {
                console.log('New service worker in installing state.');

                registration.installing.onstatechange = function () {
                    console.log('Service worker state changed to', registration.state);
                    if (registration.state == 'installed') {
                        if (!navigator.serviceWorker.controller) {
                            console.log('First install for this service worker.');
                        } else {
                            console.log('New service worker is ready to install on refresh.');
                        }
                    }
                };
            });

            // If a service worker is in 'waiting' state, then maybe the user
            // dismissed the notification when the service worker was in the
            // 'installing' state or maybe the 'updatefound' event was fired
            // before it could be listened, or something like that. Anyway, in
            // that case the notification has to be shown again.
            //
            if (registration.waiting) {
                console.log('Service working in skipwaiting state.');
            }

            // Well, really this should go into a setInterval() call, but I'm
            // including it here to be exhaustive.
            console.log('Updating service worker.');
            registration.update();
        }).catch(error => console.log('Service worker not registered (' + error +').'))
    })
} else {
    console.log('Service workers not supported.');
}
if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {

        let refreshing = false;
        navigator.serviceWorker.addEventListener('controllerchange', () => {
            console.log('New service worker in charge.');
            if (refreshing) return;
            refreshing = true;
            window.location.reload();
        });

        navigator.serviceWorker.register('/sw.js').then(registration => {
            console.log('Service worker registered.');

            // No controller for this page, nothing to do for now.
            if (!navigator.serviceWorker.controller) {
                console.log('No service worker controlling this page.');
            }    

            // A new service worker has been fetched, watch for state changes.
            //
            // This event is fired EVERY TIME a service worker is fetched and
            // succesfully parsed and goes into 'installing' state. This
            // happens, too, the very first time the page is visited, the very
            // first time a service worker is fetched for this page, when the
            // page doesn't have a controller, but in that case there's no new
            // version available and the notification must not appear.
            //
            // So, if the page doesn't have a controller, no notification shown.
            registration.addEventListener('updatefound', function () {
                console.log('New service worker in installing state.');

                registration.installing.onstatechange = function () {
                    console.log('Service worker state changed to', registration.state);
                    if (registration.state == 'installed') {
                        if (!navigator.serviceWorker.controller) {
                            console.log('First install for this service worker.');
                        } else {
                            console.log('New service worker is ready to install on refresh.');
                        }
                    }
                };
            });

            // If a service worker is in 'waiting' state, then maybe the user
            // dismissed the notification when the service worker was in the
            // 'installing' state or maybe the 'updatefound' event was fired
            // before it could be listened, or something like that. Anyway, in
            // that case the notification has to be shown again.
            //
            if (registration.waiting) {
                console.log('Service working in skipwaiting state.');
            }

            // Well, really this should go into a setInterval() call, but I'm
            // including it here to be exhaustive.
            console.log('Updating service worker.');
            registration.update();
        }).catch(error => console.log('Service worker not registered (' + error +').'))
    })
} else {
    console.log('Service workers not supported.');
}