推送通知概览

简要介绍什么是推送通知、为什么要使用推送通知以及推送通知的工作原理。

Matt Gaunt

什么是推送通知?

即使用户并未使用您的网站,推送消息也可以让您提起用户关注的信息。这类消息称为“推送”消息,因为即使用户处于非活跃状态,您也可以向用户“推送”信息。push比较推送技术拉取技术,进一步了解此概念。

通知会向用户显示小块的信息。网站可以使用通知来告知用户重要的时效性事件或用户需要采取的操作。通知的外观和风格因平台而异:

macOS 和 Android 上的通知示例。
macOS 和 Android 上的通知示例。

推送消息和通知是两种独立但相辅相成的技术。推送是一种从服务器向用户发送消息的技术,即使用户并未主动使用您的网站也是如此。通知是用于在用户设备上显示推送的信息的技术。可以在没有推送消息的情况下使用通知。有一天,您也可以在不使用面向用户的通知的情况下使用推送消息(静默推送),但浏览器目前还不允许这样做。在实践中,它们通常会一起使用。非技术用户可能不了解推送消息和通知之间的区别。在此集合中,我们所说的“推送通知”是指推送消息,随后将其显示为通知的组合。当我们说推送消息时,我们指的是技术本身的推送。我们所说的通知本身指的是通知技术。

为什么要使用推送通知?

  • 对于用户而言,推送通知是一种接收及时相关精确信息的方式。
  • 对您(网站所有者)来说,推送通知是提高用户互动度的一种方式。

推送通知是如何运作的?

概括来讲,实现推送通知的关键步骤如下:

  1. 添加客户端逻辑以请求用户授予发送推送通知的权限,然后将客户端标识符信息发送到服务器以存储在数据库中。
  2. 添加服务器逻辑,以将消息推送到客户端设备。
  3. 添加客户端逻辑,以接收已推送到设备的消息并将其显示为通知。

本页的其余部分将更详细地介绍这些步骤。

获取发送推送通知的权限

首先,您的网站需要获得用户的许可才能发送推送通知。此操作应由用户手势触发,例如点击 Do you want to receive push notifications? 提示旁边的 Yes 按钮。确认后,调用 Notification.requestPermission()。用户设备上的操作系统或浏览器可能会提供某种界面来正式确认用户想要选择接收推送通知。此界面因平台而异。

为客户端订阅推送通知

在您获得权限后,您的网站需要启动为用户订阅推送通知的流程。此操作通过 JavaScript 使用 Push API 完成。在订阅过程中,您需要提供身份验证公钥,我们稍后会对此进行详细介绍。在您启动订阅流程后,浏览器会向称为推送服务的网络服务发出网络请求,稍后我们还会对此进行详细介绍。

假设订阅成功,浏览器会返回 PushSubscription 对象。您需要长期存储这些数据。通常的做法是将信息发送到您控制的服务器,然后让该服务器将其存储在数据库中。

获取发送推送消息的权限。获取 PushSubscription。将 PushSubscription 发送到您的服务器。

发送推送消息

实际上,您的服务器并不会将推送消息直接发送给客户端,推送服务就可以做到这一点。推送服务是由用户的浏览器供应商控制的网络服务。如果要向客户端发送推送通知,您需要向推送服务发出网络服务请求。您发送到推送服务的网络服务请求称为“网络推送协议请求”。Web 推送协议请求应包含以下内容:

  • 要在消息中包含哪些数据。
  • 消息发送到哪个客户端。
  • 有关推送服务应如何传递消息的说明。例如,您可以指定推送服务应在 10 分钟后停止尝试发送消息。

通常,您通过控制的服务器发出 Web 推送协议请求。当然,您的服务器不必自行构建原始网络服务请求。有些库可以为您处理这个问题,例如 web-push-libs。但底层机制是基于 HTTP 的网络服务请求。

您的服务器向推送服务发送网络推送协议请求,推送服务将这条消息发送至用户的设备。

推送服务接收您的请求、对其进行身份验证,并将推送消息路由到相应的客户端。如果客户端的浏览器处于离线状态,推送服务会将推送消息排入队列,直到浏览器恢复在线状态。

每个浏览器都会使用它想要的任何推送服务。网站开发者无法对此进行控制这没有问题,因为 Web 推送协议请求是标准化的。也就是说,浏览器供应商使用的是哪项推送服务,就不必为了。您只需确保您的 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 推送协议请求发送到推送服务后,推送服务会使您的请求排队,直到发生以下事件之一:

  1. 客户端上线,推送服务传递推送消息。
  2. 邮件过期。

当客户端浏览器收到推送的消息时,它会解密推送消息数据,并向您的 Service Worker 分派 push 事件。Service Worker 基本上是一种可以在后台运行的 JavaScript 代码,即使您的网站未打开或浏览器已关闭也是如此。在 Service Worker 的 push 事件处理脚本中,调用 ServiceWorkerRegistration.showNotification() 以将信息显示为通知。

消息到达设备。浏览器唤醒 Service Worker。将分派推送事件。

下一步做什么

Codelab