Web 推送通知入门

2025-06-11

Web 推送通知入门

我听说过 Web 推送通知和 Service Worker 很多次,但一直没能真正实现它们,直到上周为了Just Comments做了一些小改动。所以,我决定分享一下我对这项技术的一点心得。

首先,关于 Web 推送通知的文章和实用文档已经很多了,所以我就不多说了。我会尽量总结一下我认为需要理解和掌握的知识,以便快速上手并实现一个基础版本的 Web 推送通知。

让我们从一些关键事实开始:

#1 推送通知依赖于多个独立的浏览器 API

推送通知的整个功能涉及推送 API 和通知 API,它们可以单独使用。此外,它依赖于 Service Worker,因为只有 Service Worker 才能在后台运行,即使用户关闭了发送通知的网站,也能接收推送通知。

#2 并非所有浏览器都支持推送通知

目前,IE 和 Opera Mini不支持 Service WorkersPush API,此外,iOS Safari、Android 版 Chrome、三星浏览器和 Android 版 UC 浏览器不支持Web Notifications API

这意味着您在实现推送通知时需要检测浏览器是否支持所需的 API。

工作原理大图

我创建了一个简单的图表来理解不同的 API 和概念。它通过一系列操作/关系将各个部分连接起来。

一切始于网页上的一段 JavaScript 代码,该代码注册 (1) 一个 Service Worker。Service Worker 提供 (2) 一个 Service Worker 注册对象,该对象反过来又提供 (3) 对 Push Manager 实例的访问权限。如果用户允许,推送管理器可以提供 (4) 一个 Push Subscription。此订阅对象可以发送到您的后端 (5)。在服务器上,您可以使用该订阅向用户浏览器发送一条消息 (6)。Service Worker 接收 (7) 该消息,但不会自动显示给用户。Service Worker 会解析该消息并决定如何处理。通常,Service Worker 会使用 Notification API 显示一条 Notification (8)。

编码部分

正如我在关键事实中提到的,并非所有浏览器都支持 API,因此我们需要检查用户的浏览器是否支持服务工作者:

function supportsPushNotifications() {
  return 'serviceWorker' in navigator && 'PushManager' in window;
}

supportsPushNotifications() === true // if the browser supports needed APIs
Enter fullscreen mode Exit fullscreen mode

在我们检查可以使用 Service Worker 之后,我们可以从第一步开始并注册一个 Service Worker:

navigator
  .serviceWorker
  .register('/sw.js')
  .then(swRegistration => {
    // TODO step 2 & 3 here
  })
  .catch(err => {
    console.log('serviceWorker.register failed', err);
  });
Enter fullscreen mode Exit fullscreen mode

此代码sw.js从您的网站根目录获取数据。该函数返回一个 Promise。因此,我们会在成功和出错时register处理它。.then.catch

现在,我们可以执行步骤 2 和 3,这需要swRegistration

const applicationServerKey = '';
swRegistration
  .pushManager
  .getSubscription()
  .then(subscription => {
    const isSubscribed = !(subscription === null);
    if (!isSubscribed) {
      return swRegistration.pushManager
        .subscribe({
          userVisibleOnly: true,
          applicationServerKey,
        })
        .then(sendSubscriptionToServer);
    }
    sendSubscriptionToServer(subscription);
  })
  .catch(err => {
    console.log('getSubscription failed', err);
  });
Enter fullscreen mode Exit fullscreen mode

applicationServerKey暂时不用担心。applicationServerKey允许将订阅与您的服务器关联。稍后我会解释如何获取此密钥。

那么这里发生了什么:我们调用该pushManager.getSubscription方法,如果用户已经允许推送通知,则返回订阅,null否则返回。如果用户已经订阅,我们可以将其发送到后端。如果没有,我们调用该方法pushManager.subscribe询问用户是否允许推送通知。

现在,对于步骤 5,您可以使用任何您喜欢的方法将订阅对象发送到服务器。我建议先使用 进行字符串化JSON.stringify(subscription)

为了从服务器向客户端发送消息,我建议使用web-push以下模块:

const webpush = require('web-push');

const vapidKeys = {
  publicKey: '',
  privateKey: '',
};

webpush.setVapidDetails(
  'mailto:your@email',
  vapidKeys.publicKey,
  vapidKeys.privateKey
);

webpush.sendNotification(
  JSON.parse(subscription),
  JSON.stringify({
    title: 'Title',
    icon: 'https://your-site.com/assets/push-icon.png',
    body: 'Body',
    url: 'https://your-site.com/url-to-open',
  })
)
Enter fullscreen mode Exit fullscreen mode

现在在步骤 7 和 8 中,我们回到sw.js负责接收和显示推送消息的服务工作线程代码:

self.addEventListener('push', function(event) {
  const message = JSON.parse(event.data.text());
  const title = message.title;
  const url = message.url;
  const options = {
    body: message.body,
    icon: message.icon,
    badge: message.badge,
    data: url,
  };
  event.waitUntil(self.registration.showNotification(title, options));
});

self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  event.waitUntil(clients.openWindow(event.notification.data));
});

Enter fullscreen mode Exit fullscreen mode

这里定义了两个事件监听器。通过push监听器,我们解析消息并调用相应的showNotification方法来显示通知。然后,notificationclick我们关闭通知并导航到推送消息发送的 URL。

生成密钥

你可以使用该web-push库生成密钥。密钥生成只需执行一次。前端和后端都使用相同的公钥,后端仅使用私钥:

const webpush = require('web-push');
const vapidKeys = webpush.generateVAPIDKeys();
console.log(vapidKeys);
Enter fullscreen mode Exit fullscreen mode

您应该在需要的地方指定前面的代码片段中的键。

结论

我发现推送通知的 API 相当简单直接。尽管如此,一开始还是需要花不少时间才能理解所有概念和运作机制。

希望这些笔记对您有所帮助,并在您需要实现推送通知时再次参考。如果这种情况发生,请不要在网页加载时立即请求权限:这很烦人,大多数人都会屏蔽它。

感谢阅读!

鏂囩珷鏉ユ簮锛�https://dev.to/orkon/getting-started-with-web-push-notifications-1poe
PREV
职业生涯回顾
NEXT
无需构建即可进行开发 (1):简介 无需构建即可进行开发:简介