使用 Web 推送

在扩展程序中,您可以使用任何推送提供方来发送推送通知和消息。来自 Push API 的推送一经收到,就会立即由您的 Service Worker 处理。如果 Service Worker 已暂停,推送会将其唤醒。在扩展程序中使用该 API 的流程与在开放式网络中使用该 API 的流程完全相同。

获取使用 Push API 的权限

在普通网站上注册推送服务器时,系统会向用户显示权限提示,让用户授予或拒绝权限。使用不会显示提示的扩展服务。如需在扩展程序中使用 Push API,您需要在 manifest.json 中设置 notifications 权限

  {
    "manifest_version": 3,
    ...
    "permissions": ["notifications"]

如果您缺少此权限,则与 registration.pushManager 的任何互动都会导致立即出错,这与用户拒绝授予权限的结果相同。此外,请注意,notifications 权限会导致在安装时显示权限警告。在用户批准新的权限请求之前,Chrome 还会针对所有现有安装停用该扩展程序。如需详细了解如何处理此问题,请参阅权限警告指南

推送提供商和推送服务

将权限添加到 manifest.json 后,您需要配置后端与扩展程序之间的连接。此连接可分为两部分:推送提供方和推送服务。提供方是指您用于向推送服务发送消息的 SDK。有很多不同的选项,任何推送提供方都可以用于 Push API(尽管他们可能不提供可简化集成过程的 SDK)。您需要通过实验来了解提供商的 SDK 可以实现哪些功能。推送服务是指最终用户的设备注册的服务,以便在推送提供方发送任何推送消息时收到提醒。您无法控制这一点,因为它是硬编码到各个浏览器中的。对于 Chrome,Firebase Cloud Messaging 是推送服务。推送给 Chrome 用户的任何消息都将通过该服务进行路由。

自行托管推送提供程序

任何推送提供商都可以使用,但并非所有提供商都提供可在 Service Worker 中使用的 SDK。如果您在运行该应用时遇到问题,需要咨询您的提供商。不过,您无需使用公共提供方。借助 web-push 等库,您可以自行托管后端。

您可以使用 web-push-codelab.glitch.me 测试此库。具体来说,您需要复制推送服务器的 VAPID 公钥,以便在浏览器中生成推送订阅。此公钥实际上是一个 base64 编码的二进制值,需要对其进行解码并转换为 Uint8Array,才能向浏览器的 Push manager 注册。虽然有库可用于执行此逻辑,但以下内容就足够了。

function urlB64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');

  const rawData = atob(base64);
  const outputArray = new Uint8Array(rawData.length);

  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
}

所提供的值会传递到推送管理器中

const SERVER_PUBLIC_KEY = '_INSERT_VALUE_HERE_';
const applicationServerKey = urlB64ToUint8Array(SERVER_PUBLIC_KEY);

async function subscribe() {
  try {
    let subscription = await self.registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey
    });

    console.log(`Subscribed: ${JSON.stringify(subscription,0,2)}`);

    return subscription
  } catch (error) {
    console.error('Subscribe error: ', error);
  }
}

const subscription = await subscribe();

subscribe 函数会返回一个 PushSubscription,该对象包含推送服务器的元数据。由于您使用的是 web-push-codelab.glitch.me,因此需要将此值复制到网页的“推送订阅”部分。

获得 PushSubscription 后,您就可以在扩展程序的 Service Worker 中注册推送消息的监听器了。

self.addEventListener('push', function (event) {
  console.log(`Push had this data/text: "${event.data.text()}"`);
});

设置好监听器后,您可以在 web-push-codelab.glitch.me 上提交消息,消息将记录到服务工作线程的控制台中。

由于它是一种开放式网络标准,因此有大量关于如何实现 Web 推送的现有文档,包括 Chrome 的博客。如需查看本文介绍的示例的完整版本,请访问我们的扩展程序示例代码库

静默推送

自 Chrome 88 中引入 Manifest v3 以来,您一直能够在 Manifest v3 扩展程序中接收推送通知。不过,一直以来都有一个要求,即通知必须显示某种用户可见的提示,例如网页通知。如果您想向扩展程序推送命令或数据更新,但又不想用不必要的信息打扰用户,那么这种方式的实用性就会大打折扣。自 Chrome 121 起,扩展程序能够将 userVisibleOnly 设置为 false。您现在可以向用户发送静默的非用户面向型推送通知。如需使用此功能,请在调用 pushManager.subscribe 时将 userVisibleOnly 设置为 false

let subscription = await self.registration.pushManager.subscribe({
  userVisibleOnly: false,
  applicationServerKey
});