在此 Codelab 中,您将使用 Service Worker 以管理通知。 此处的说明假定您已熟悉 以及请求通知权限和发送通知的基础知识。 如果您需要回顾一下通知,请参阅 Notifications API 使用入门 Codelab。如需详细了解 Service Worker,请参阅 Matt Gaunt 的 Service Worker 简介。
重新合成示例应用并在新标签页中查看
系统会自动屏蔽嵌入式 Glitch 应用的通知,因此您无法在此页面上预览该应用。此时,您需要执行以下操作:
- 点击 Remix to Edit 以使项目可修改。
- 如需预览网站,请按查看应用。然后按 全屏 。
系统应该会在新的 Chrome 标签页中打开 Glitch。
在学习此 Codelab 时,请更改此页面上嵌入式 Glitch 中的代码。使用已发布的应用刷新新标签页以查看更改。
熟悉示例应用和起始代码
首先,在新 Chrome 标签页中查看正在运行的应用:
- 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
点击控制台标签页。
确保在级别下拉菜单中选择信息选项 (位于过滤条件框旁边)。
在实时应用的开发者工具控制台中,您应该会看到以下控制台消息:
TODO: Implement getRegistration()
。这是来自您将在此 Codelab 中实现的函数桩的消息。
现在,我们来看看本页嵌入式 Glitch 中的示例应用代码。
在嵌入式 Glitch 中,查看
public/index.js
:您将实现的函数有四个存根:
registerServiceWorker
、getRegistration
、unRegisterServiceWorker
和sendNotification
。requestPermission
函数会请求用户授予发送通知的权限。如果您学习了开始使用 Notifications API 的 Codelab,就会注意到此处使用了其requestPermission
函数。唯一的区别是,现在还会在解析权限请求后更新界面。updateUI
函数可刷新应用的所有按钮和消息。initializePage
函数在浏览器中针对 Service Worker 功能执行功能检测,并更新应用界面。脚本将等待页面加载,然后初始化页面。
在嵌入式 Glitch 中,打开
public/service-worker.js
。顾名思义,您需要向应用添加代码,以便将此文件注册为 Service Worker。
尽管该文件尚未被应用使用,但它包含一些起始代码,这些代码将在激活 Service Worker 时向控制台输出消息。
您将向
public/service-worker.js
添加代码,以便在 Service Worker 收到通知时处理通知。
注册 Service Worker
在此步骤中,您将编写可运行
当用户点击应用界面中的 Register Service Worker 时触发。
此代码会将 public/service-worker.js
注册为 Service Worker。
在嵌入式 Glitch 编辑器中,打开
public/index.js
。 将registerServiceWorker
函数替换为以下代码:// Use the Service Worker API to register a service worker. async function registerServiceWorker() { await navigator.serviceWorker.register('./service-worker.js') updateUI(); }
请注意,
registerServiceWorker
使用async function
声明,以便更加方便地处理 promise。这样,您就可以await
处理Promise
的解析值。例如,在更新界面之前,上述函数会等待注册 Service Worker 的结果。如需了解详情,请参阅 MDN 上的await
。现在,用户可以注册 Service Worker,您可以获取对 Service Worker 注册对象的引用。在
public/index.js
中,将getRegistration
函数替换为以下代码:// Get the current service worker registration. function getRegistration() { return navigator.serviceWorker.getRegistration(); }
上面的函数使用 Service Worker API 来获取当前的 Service Worker 注册(如果存在)。 它会更方便地获取对 Service Worker 注册的引用。
要完成 Service Worker 注册功能,请添加用于取消注册 Service Worker 的代码。将
unRegisterServiceWorker
函数替换为以下代码:// Unregister a service worker, then update the UI. async function unRegisterServiceWorker() { // Get a reference to the service worker registration. let registration = await getRegistration(); // Await the outcome of the unregistration attempt // so that the UI update is not superceded by a // returning Promise. await registration.unregister(); updateUI(); }
在您当前查看应用的标签页中,重新加载页面。Register Service Worker 和 Unregister Service Worker 按钮现在应该可以正常使用了。
向 Service Worker 发送通知
在此步骤中,您将编写相应代码,当用户点击应用界面中的发送通知时,这些代码将会运行。这段代码将创建一个通知,检查 Service Worker 是否已注册,然后使用其 postMessage
方法将该通知发送到 Service Worker。
在嵌入式 Glitch 编辑器中,打开 public/index.js
并
将 sendNotification
函数替换为以下代码:
// Create and send a test notification to the service worker.
async function sendNotification() {
// Use a random number as part of the notification data
// (so you can tell the notifications apart during testing!)
let randy = Math.floor(Math.random() * 100);
let notification = {
title: 'Test ' + randy,
options: { body: 'Test body ' + randy }
};
// Get a reference to the service worker registration.
let registration = await getRegistration();
// Check that the service worker registration exists.
if (registration) {
// Check that a service worker controller exists before
// trying to access the postMessage method.
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage(notification);
} else {
console.log('No service worker controller found. Try a soft reload.');
}
}
}
该代码的作用如下:
sendNotification
是一个异步函数,因此您可以使用await
获取对 Service Worker 注册的引用。Service Worker 的
postMessage
方法将数据从应用发送到 Service Worker。如需了解详情,请参阅有关 postMessage 的 MDN 文档。该代码在尝试访问
postMessage
函数之前,会检查是否存在navigator.serviceWorker.controller
属性。如果没有活跃的 Service Worker,或者页面已被强制刷新(Shift+
重新加载),则navigator.serviceWorker.controller
将为null
。如需了解详情,请参阅关于 MDN 的 ServiceWorker 控制器文档。
在 Service Worker 中处理通知
在此步骤中,您将在 Service Worker 中编写代码,用于处理发布到 Service 的消息并向用户显示通知。
在嵌入式 Glitch 编辑器中,打开 public/service-worker.js
。将以下代码添加到文件末尾:
// Show notification when received
self.addEventListener('message', (event) => {
let notification = event.data;
self.registration.showNotification(
notification.title,
notification.options
).catch((error) => {
console.log(error);
});
});
以下是快速说明:
self
是对 Service Worker 本身的引用。尽管 Service Worker 现在负责显示通知,但主应用界面仍负责从用户那里获取通知权限。如果未授予权限,
showNotification
返回的 promise 会被拒绝。上面的代码使用catch
块来避免未捕获的Promise
拒绝错误,并更加妥善地处理此错误。
如果您遇到困难,请参阅 glitch.com/edit/#!/codelab-notifications-service-worker-completed,获取已完成的代码。
继续学习本系列中的下一个 Codelab:构建推送通知服务器。