简要介绍什么是推送通知、为什么要使用推送通知以及推送通知的工作原理。
什么是推送通知?
借助推送消息,您可以让用户即使在未使用您的网站时也能注意到相关信息。之所以称为推送消息,是因为您可以向用户“推送”信息,即使用户处于非活跃状态也是如此。比较推送技术与拉取技术,进一步了解此概念。
通知会向用户显示少量信息。网站可以使用通知告知用户重要且紧急的事件,或用户需要执行的操作。通知的外观和风格因平台而异:
推送消息和通知是两种不同的但互为补充的技术。 推送是一种技术,可让您从服务器向用户发送消息,即使用户未主动使用您的网站也是如此。通知是一种在用户设备上显示推送信息的技术。您可以在不使用推送消息的情况下使用通知。将来,您或许还可以使用不向用户显示通知的推送消息(静默推送),但浏览器目前不允许这样做。在实际使用中,它们通常一起使用。 非技术用户可能不了解推送消息和通知之间的区别。在本集合中,当我们说“推送通知”时,是指推送消息后将其显示为通知的组合。当我们所说的“推送消息”本身是指推送技术本身。当我们说“通知”时,是指通知技术本身。
为何使用推送通知?
- 对于用户而言,推送通知是一种接收及时、相关且准确信息的方式。
- 对于网站所有者来说,推送通知是提高用户互动度的一种方式。
推送通知的运作方式
概括来讲,实现推送通知的关键步骤如下:
- 添加客户端逻辑以向用户请求发送推送通知的权限,然后将客户端标识符信息发送到您的服务器以存储在数据库中。
- 添加服务器逻辑以将消息推送到客户端设备。
- 添加客户端逻辑,以接收已推送到设备的消息并将其显示为通知。
本页面的其余部分将更详细地介绍这些步骤。
获取发送推送通知的权限
首先,您的网站需要征得用户的许可才能发送推送通知。此操作应由用户手势触发,例如点击 Do you want to receive push notifications?
提示旁边的 Yes 按钮。确认后,调用 Notification.requestPermission()
。用户设备上的操作系统或浏览器可能会显示某种界面,以正式确认用户想要选择接收推送通知。此界面因平台而异。
为客户端订阅推送通知
获得权限后,您的网站需要发起用户订阅推送通知的流程。这通过 JavaScript 使用 Push API 完成。您需要在订阅过程中提供一个公共身份验证密钥,稍后会详细介绍。您启动订阅流程后,浏览器会向一项名为推送服务的 Web 服务发出网络请求,您稍后还会详细了解这项服务。
假设订阅成功,浏览器会返回 PushSubscription
对象。您需要长期存储这些数据。这通常是通过将信息发送到您控制的服务器,然后将信息存储在数据库中来实现的。
发送推送消息
您的服务器实际上不会直接向客户端发送推送消息。推送服务可以做到这一点。推送服务是由用户的浏览器供应商控制的 Web 服务。如果要向客户端发送推送通知,您需要向推送服务发出网络服务请求。您发送给推送服务的 Web 服务请求称为 Web 推送协议请求。Web 推送协议请求应包含:
- 要包含在消息中的数据。
- 要将消息发送到的客户端。
- 有关推送服务应如何传送消息的说明。例如,您可以指定推送服务应在 10 分钟后停止尝试发送消息。
通常,您会通过自己控制的服务器发出 Web 推送协议请求。当然,您的服务器不必自行构建原始 Web 服务请求。有些库可以为您处理此问题,例如 web-push-libs。但底层机制是通过 HTTP 发出的 Web 服务请求。
推送服务会接收您的请求、对其进行身份验证,并将推送消息路由到相应的客户端。如果客户端的浏览器处于离线状态,推送服务会将推送消息加入队列,直到浏览器恢复在线状态。
每个浏览器都可以使用它想要的任何推送服务。作为网站开发者,您无法控制这一点。这不是问题,因为 Web Push 协议请求是标准化的。换句话说,您无需关心浏览器供应商使用的是哪种推送服务。您只需确保您的 Web 推送协议请求符合规范即可。除此之外,规范还规定请求必须包含特定标头,并且数据必须以字节流的形式发送。
不过,您需要确保将 Web 推送协议请求发送到正确的推送服务。浏览器在订阅过程中返回给您的 PushSubscription
数据提供了这些信息。PushSubscription
对象如下所示:
{
"endpoint": "https://fcm.googleapis.com/fcm/send/c1KrmpTuRm…",
"expirationTime": null,
"keys": {
"p256dh": "BGyyVt9FFV…",
"auth": "R9sidzkcdf…"
}
}
endpoint
的网域本质上是推送服务。endpoint
的路径是客户端标识符信息,可帮助推送服务准确确定要将消息推送到哪个客户端。
keys
用于加密,详见下文。
加密推送消息
您发送到推送服务的数据必须经过加密。这样可以防止推送服务查看您发送给客户端的数据。请注意,浏览器供应商决定使用哪种推送服务,而推送服务在理论上可能不安全。您的服务器必须使用 PushSubscription
中提供的 keys
对其 Web 推送协议请求进行加密。
对 Web 推送协议请求进行签名
推送服务提供了一种方法,可防止任何其他人向您的用户发送消息。从技术上讲,您不必这样做,但最简单的 Chrome 实现方式却需要这样做。在 Firefox 中,此设置是可选的。其他浏览器未来可能也需要此属性。
此工作流涉及应用专有的私钥和公钥。身份验证过程大致如下:
- 生成私钥和公钥是一次性任务。私钥和公钥的组合称为应用服务器密钥。您可能还会看到它们被称为 VAPID 密钥。VAPID 是定义此身份验证流程的规范。
- 通过 JavaScript 代码将客户端订阅推送通知时,您需要提供公钥。当推送服务为设备生成
endpoint
时,它会将提供的公钥与endpoint
相关联。 - 发送 Web 推送协议请求时,您需要使用私钥对一些 JSON 信息进行签名。
- 当推送服务收到您的 Web 推送协议请求时,它会使用存储的公钥对已签名的信息进行身份验证。如果签名有效,则推送服务会知道请求来自具有匹配私钥的服务器。
自定义推送消息的传送
Web 推送协议请求规范还定义了一些参数,可让您自定义推送服务尝试向客户端发送推送消息的方式。例如,您可以自定义:
- 消息的存活时间 (TTL),用于指定推送服务应尝试传送消息的时长。
- 消息的紧急程度。如果推送服务仅传送高优先级消息以延长客户端的电池续航时间,则此属性非常有用。
- 消息的主题,系统会将同一主题的所有待处理消息替换为最新消息。
接收并以通知的形式显示推送的消息
将 Web 推送协议请求发送到推送服务后,推送服务会将您的请求保持在队列中,直到发生以下任一事件:
- 客户端上线,推送服务传送推送消息。
- 消息过期。
当客户端浏览器收到推送消息时,它会解密推送消息数据,并将 push
事件分派给您的服务工作器。Service Worker 基本上就是可以在后台运行的 JavaScript 代码,即使您的网站未打开或浏览器已关闭也是如此。在 Service Worker 的 push
事件处理程序中,您可以调用 ServiceWorkerRegistration.showNotification()
以将信息显示为通知。