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

WordPress Web推送插件:Service Worker重复发送通知问题

解决WordPress Web推送通知重复且部分无跳转链接的问题

嘿,针对你遇到的这个问题——用户订阅后欢迎通知正常,但新文章推送时部分用户收到多条通知且仅一条带跳转链接,我结合你提供的代码梳理了根源和修复方案:

问题根源分析

  1. Service Worker缺失Push事件处理逻辑:你当前的service-worker.js只监听了install、activate和message事件,完全没有处理推送核心的push事件。这意味着通知展示可能依赖外部加载的脚本(比如你注册SW时带的notifymsgjs参数对应的文件),如果外部脚本重复加载或SW更新时重复绑定事件,就会导致多条通知。

  2. Service Worker重复注册与强制更新:在generate-token.js里,每次UDID变化就会重新注册SW,还立刻调用reg.update()。频繁的更新会让SW多次激活,可能触发重复的推送监听逻辑。

  3. 推送Payload处理不严谨:如果后端发送的推送数据没有稳定携带跳转链接,或者前端处理逻辑只有第一次触发时解析链接,后续重复通知就会丢失链接信息。

具体修复步骤

1. 完善Service Worker的Push事件处理

修改service-worker.js,添加push和notificationclick事件监听,统一接管通知逻辑,避免依赖外部脚本的不确定性:

self.addEventListener('install', function(event) {
    console.log('installed!');
    event.waitUntil(self.skipWaiting()); // 让新SW立即激活
});

self.addEventListener('activate', function(event) {
    console.log('activated!');
    event.waitUntil(self.clients.claim()); // 接管所有打开的页面
});

self.addEventListener('message', function(event) {
    // 保留原有消息处理逻辑
});

// 新增:处理推送事件,确保只显示一条通知
self.addEventListener('push', function(event) {
    const payload = event.data ? event.data.json() : {};
    const notificationOptions = {
        body: payload.body || '您关注的网站发布了新文章',
        icon: payload.icon || '/wp-content/plugins/your-plugin/icon.png', // 替换为你的插件图标路径
        tag: 'new-post-notification', // 用tag确保同类型通知只会显示一条
        data: {
            url: payload.url || self.location.origin // 强制携带跳转链接,兜底为官网
        }
    };

    event.waitUntil(
        // 先关闭已有同tag的通知,再显示新的
        self.registration.getNotifications({tag: 'new-post-notification'})
            .then(notifications => {
                notifications.forEach(n => n.close());
                return self.registration.showNotification(payload.title || '新文章通知', notificationOptions);
            })
    );
});

// 新增:处理通知点击,确保跳转正确链接
self.addEventListener('notificationclick', function(event) {
    event.notification.close();
    // 打开指定链接,没有的话打开官网
    event.waitUntil(
        clients.openWindow(event.notification.data.url)
    );
});

2. 优化Service Worker注册逻辑

在generate-token.js中,避免不必要的重复注册和强制更新,只在未注册时才执行注册:

// 替换原有的SW注册代码块
if ('serviceWorker' in navigator) {
    var myId = obj.messagingSenderId;
    const swUrl = `${notifyonnewpost.message_sw_path}?messagingSenderId=${myId}&notifyappjs=${notifyonnewpost.notify_app_path}&notifymsgjs=${notifyonnewpost.notify_msg_path}`;
    
    // 先检查是否已注册该SW
    navigator.serviceWorker.getRegistration(swUrl)
        .then(existingReg => {
            if (!existingReg) {
                // 未注册时才进行注册操作
                return navigator.serviceWorker.register(swUrl);
            }
            return existingReg;
        })
        .then(reg => {
            console.log(`SW registration succeeded. Scope is ${reg.scope}`);
            messaging.useServiceWorker(reg);
            // 移除强制更新:reg.update(),除非你确定需要强制用户更新SW,否则不要频繁调用
        })
        .catch(err => {
            console.error(`SW registration failed with error ${err}`);
        });
}

3. 确保后端推送Payload携带正确链接

在WordPress端的推送触发代码中,确保每次发送的推送数据都包含url字段,指向对应的文章页面。比如后端构造的JSON应该是:

{
    "title": "你的新文章标题",
    "body": "文章的简短摘要",
    "url": "https://your-wordpress-site.com/your-new-post/",
    "icon": "https://your-wordpress-site.com/wp-content/plugins/your-plugin/assets/notification-icon.png"
}

4. 检查后端推送逻辑是否重复触发

确认WordPress中发布文章的钩子(比如publish_post)是否被多次绑定,或者是否存在异步逻辑导致推送请求被发送多次,这也是造成多条通知的常见原因。

验证方法

  1. 让测试用户清除浏览器的Service Worker和本地存储,重新订阅
  2. 发布一篇测试文章,检查通知是否只出现一次,且点击能正确跳转到文章页面
  3. 在不同浏览器(Chrome、Firefox)和设备上测试,确保问题不再复现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:22:38