当前位置: 首页 > 知识库问答 >
问题:

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

南门刚捷
2023-03-14

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

// Register service worker.
let newWorker;
if ('serviceWorker' in navigator) {
    function showUpdateNotification () {
        document.getElementById('updatenotification').style['visibility'] = 'visible';
    };

    window.addEventListener('load', () => {
        navigator.serviceWorker.register('/sw.js').then(registration => {
            console.log('Service worker registered at scope "' + registration.scope + '".');

            // 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();
            // }
            registration.onupdatefound = () => {
                console.log('Service worker update found.');
                console.log('Installing service worker is', registration.installing);
                newWorker = registration.installing;

                newWorker.onstatechange = function () {
                    console.log('Service worker state changed to', newWorker.state);
                    if (newWorker.state == 'installed' && navigator.serviceWorker.controller) {
                        console.log('New service worker is ready to install on refresh.');
                        showUpdateNotification();
                    }
                };
            };
            console.log('Updating service worker.');
            registration.update();
        }).catch(error => console.log('Service worker not registered (' + error +').'))
    })
}

当然,该代码是有效的,因为如果准备好安装新版本的服务辅助角色,它会在网页上显示通知。

问题是,如果在该点重新加载页面,则不再显示通知,因为如果安装了新的服务工作人员并等待激活,则不再触发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();
// }

此代码在注册时检查是否有某个服务工作人员处于等待状态,并再次显示通知。

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

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

非常感谢。

共有1个答案

曹镜
2023-03-14

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

我认为下面的代码或多或少涵盖了对服务工作者整个生命周期的处理,并且可以用作非非常复杂的样板代码。

我使用来自无数来源的信息设计了这段代码,包括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.');
}
 类似资料:
  • 演示视频:https://www.youtube.com/watch?v=UBfnvx6jC_A 我学习了Udacity的离线Web应用程序课程,以便让我的应用程序离线工作。这是我的密码: 主要的js 服务人员。js 当我处于一个安装了服务人员并处于活动状态,并且缓存了我所有的东西的状态时,就会出现问题。当我打开开发工具并在Chrome中签入“重新加载时更新”时,如果我重新加载: 页面看起来相同,

  • 我一直在阅读《html5rocks服务工作者简介》一文,并创建了一个基本的服务工作者,它可以缓存页面、JS和CSS,并按预期工作: 当我对CSS进行更改时,由于服务人员正在从缓存中正确返回CSS,因此不会拾取此更改。 我陷入困境的地方是,如果我要更改HTML、JS或CSS,我如何确保服务人员可以从服务器加载较新版本,而不是从缓存加载?我曾尝试在CSS导入上使用版本戳,但似乎不起作用。

  • 问题内容: 我正在辩论应该如何学习。主要是,如果我从数据库中获取大量信息以将其加载到页面上,那么最好的方式是操纵页面而不需要重新加载。使用XML之类的东西是最好的选择,还是我应该使用的其他东西。我知道其中很多使用HTML Dom和XML Dom,但是我不想开始学习我不需要的东西。 问题答案: 您正在寻找的技术名称是AJAX,它代表异步Javascript和XML(尽管目前大多数AJAX使用JSON

  • 问题内容: 我正在从JSF应用程序发送电子邮件。我需要它,以便当我发送电子邮件时,显示FacesMessage确认操作,然后浏览器重新加载到同一页面。我的代码显示了面孔,但没有重新加载同一页面。 这是我尝试过的,此代码重新加载页面,但未显示FacesMessage。 这是我发送电子邮件页面的代码: 请帮忙 问题答案: 如果要跨重定向保留,则应在对象上设置为。该范围是JSF2推出了新的范围。范围(和

  • 情况: 在我的网站上。com/game,我在 在我的服务器上,的最大值为。 问题: 。 问题是,每当用户访问,它显示空页面,不再执行任何操作。我无法让客户端获取新的。 如何让客户端获取新的?

  • 在教程的帮助下,我编写了一个服务人员: 它总是先从缓存服务,然后获取所有文件,并在页面重新加载时更新。 Service Worker在我的服务器上的每个超文本标记语言文件中都是这样注册的: 现在的问题是,当我转到一个尚未缓存的页面时,它首先向我显示默认的Chrome错误(以及“不匹配”promise拒绝)。 软件会在向客户机显示错误页面的同时获取它,并在重新加载时再次工作(因为它是从缓存提供服务的