推送通知概述

推送通知概述,包括其定义、用途和工作原理。

什么是推送通知?

推送消息使您能够将信息传递给用户,即使他们没有在使用您的网站。 它们之所以被称为推送消息,是因为您可以将信息“推送”给用户,即使他们不活跃。 将推送技术拉取技术进行比较,以进一步理解这个概念。

通知向用户显示少量信息。 网站可以使用通知来告知用户重要的、时间敏感的事件,或用户需要采取的操作。 通知的外观和风格因平台而异

Examples of notifications on macOS and Android.
macOS 和 Android 上的通知示例。

推送消息和通知是两种独立但互补的技术。 推送是一种将消息从您的服务器发送给用户的技术,即使他们没有积极使用您的网站。 通知是一种在用户设备上显示推送信息的技术。 可以在不使用推送消息的情况下使用通知。 有一天,也可能可以在没有面向用户的通知的情况下使用推送消息(静默推送),但浏览器目前不允许这样做。 在实践中,它们通常一起使用。 非技术用户可能不会理解推送消息和通知之间的区别。 在本集合中,当我们说推送通知时,我们指的是推送消息然后将其显示为通知的组合。 当我们说推送消息时,我们指的是推送技术本身。 当我们说通知时,我们指的是通知技术本身。

为什么使用推送通知?

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

推送通知是如何工作的?

从高层次来看,实现推送通知的关键步骤是

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

本页面的其余部分更详细地解释了这些步骤。

获取发送推送通知的权限

首先,您的网站需要获得用户的许可才能发送推送通知。 这应该由用户手势触发,例如单击 您是否希望接收推送通知? 提示旁边的按钮。 确认后,调用 Notification.requestPermission()。 用户设备上的操作系统或浏览器可能会显示某种 UI,以正式确认用户想要选择接收推送通知。 此 UI 在不同平台上有所不同。

订阅客户端以接收推送通知

获得许可后,您的网站需要启动将用户订阅到推送通知的过程。 这是通过 JavaScript 使用 Push API 完成的。 您需要在订阅过程中提供公共身份验证密钥,稍后您将了解更多相关信息。 在您启动订阅过程后,浏览器会向称为推送服务的 Web 服务发出网络请求,您稍后也将了解更多相关信息。

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

Get permission to send push messages. Get PushSubscription. Send
PushSubscription to your server.

发送推送消息

您的服务器实际上并没有直接向客户端发送推送消息。 推送服务会执行此操作。 推送服务是由用户浏览器供应商控制的 Web 服务。 当您想要向客户端发送推送通知时,您需要向推送服务发出 Web 服务请求。 您发送给推送服务的 Web 服务请求称为 Web 推送协议请求。 Web 推送协议请求应包括

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

通常,您通过您控制的服务器发出 Web 推送协议请求。 当然,您的服务器不必自己构造原始 Web 服务请求。 有一些库可以为您处理,例如 web-push-libs。 但底层机制是通过 HTTP 的 Web 服务请求。

Your server sends a web push protocol request to the push service and the push service sends to the message to the user's device.

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

每个浏览器都使用它想要的任何推送服务。 作为网站开发人员,您对此没有控制权。 这不是问题,因为 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. 消息过期。

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

Message arrives on device. Browser wakes up service worker. Push event is dispatched.

下一步

代码实验室