You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Service Worker中addEventListener事件参数的使用及推送标题异常修复

解决Service Worker Push事件中标题显示undefined的问题

我来帮你搞定这个推送通知标题显示undefined的问题!你的核心问题出在Service Worker里处理push事件参数的方式上——你把e.data.json当成了属性来用,但它其实是一个需要调用的方法。下面我给你一步步拆解修正方案,还有完整的示例代码。

1. 修正Service Worker中的push事件处理代码

你当前的代码里写的是const data = e.data.json;,这里少了括号,应该调用json()方法来解析推送的payload。另外,为了避免解析失败(比如payload格式错误),最好加上错误处理:

console.log('Service Worker Loaded.');

self.addEventListener('push', async (e) => {
  try {
    // 关键:调用json()方法解析推送数据
    const data = await e.data.json();
    console.log('Push Received:', data);
    
    self.registration.showNotification(data.title, {
      body: data.body || 'It is time to go for lunch.',
      icon: 'MyLogo.png'
    });
  } catch (err) {
    console.error('解析推送数据失败:', err);
    // 显示默认通知作为降级处理
    self.registration.showNotification('新消息提醒', {
      body: '您有一条未读通知',
      icon: 'MyLogo.png'
    });
  }
});

2. 确认后端(index.js)的payload结构与配置

你的后端代码生成的payload结构是正确的,但要确保已经正确配置了webPush的VAPID密钥,不然推送请求可能会失败:

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

// 配置你的VAPID密钥(提前生成好的公钥和私钥)
const vapidKeys = {
  publicKey: '你的VAPID公钥',
  privateKey: '你的VAPID私钥'
};

webpush.setVapidDetails(
  'mailto:your-email@example.com', // 联系邮箱,用于推送服务识别
  vapidKeys.publicKey,
  vapidKeys.privateKey
);

// Subscribe Route
app.post('/subscribe', (req, res) => {
  const subscription = req.body;
  res.status(201).json({}); // 返回201表示资源创建成功

  // 构造包含标题和内容的payload,让通知更灵活
  const payload = JSON.stringify({
    title: 'This is a payload-title',
    body: '这是一条来自后端的推送通知'
  });

  webpush.sendNotification(subscription, payload)
    .catch(err => console.error('推送请求失败:', err));
});

3. 前端订阅代码的关键细节

你的前端订阅代码整体没问题,但要确保urlBase64ToUint8Array函数的实现是正确的,这个函数负责把VAPID公钥转换成Service Worker能识别的格式,标准实现如下:

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

  const rawData = window.atob(base64);
  return Uint8Array.from([...rawData].map(char => char.charCodeAt(0)));
}

完整流程验证

按照上面的修正,整个推送流程会正常运行:

  • 前端注册Service Worker并完成推送订阅,将订阅对象发送给后端保存
  • 后端需要推送时,构造包含title(可选body)的payload,调用webpush.sendNotification发起推送
  • Service Worker接收push事件,调用e.data.json()解析payload,用解析出的data.title显示通知

这样就能彻底解决标题显示undefined的问题啦!

内容的提问来源于stack exchange,提问作者Michel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:44:41