5月31日 17:42

PWA 推送通知怎么实现才不容易被用户拒绝?

PWA 推送通知的技术链路并不复杂:页面请求权限,PushManager 创建订阅,服务端保存 endpoint 和密钥,Service Worker 收到 push 后展示通知。真正难的是边界和时机:过早弹权限会被拒绝,订阅过期不清理会浪费推送额度,通知没价值会被系统静音。

追问

推送通知必须有哪些组件?

至少需要 Notification API、Push API、Service Worker、服务端逻辑和 VAPID 密钥。Notification API 负责展示通知,Push API 负责订阅浏览器推送通道,Service Worker 负责后台接收 push 事件。取舍上,前端只做订阅和展示,定向发送、频控和权限状态管理应该放在服务端。边界是 Web Push 不是 WebSocket,它不能保证实时到达,也不适合承载大块业务数据。

什么时候请求通知权限比较合适?

最好在用户完成一次明确动作后再请求,比如关注价格、订阅课程更新、打开“提醒我”开关。页面加载时直接请求是常见踩坑,用户还不了解价值就会关掉权限。权限一旦被拒绝,很多浏览器不会让你反复弹窗,只能引导用户去设置里改。实际项目里先用站内弹层解释价值,用户确认后再调用 Notification.requestPermission。

js
async function subscribe(registration, publicKey) { if (Notification.permission !== 'granted') return null; return registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(publicKey) }); }

服务端发送推送时要注意什么?

服务端要保存 subscription 的 endpoint、p256dh、auth,还要记录用户、设备和订阅时间。发送失败时不能只打日志,410 或 404 通常表示订阅失效,需要从数据库删除。取舍上,群发通知要做队列和限速,不要在一次 HTTP 请求里同步推给所有人。通知 payload 建议只放标题、摘要和跳转地址,详情打开页面后再拉接口。

js
webpush.setVapidDetails('mailto:ops@example.com', publicKey, privateKey); await webpush.sendNotification(subscription, JSON.stringify({ title: '订单状态更新', body: '你的订单已发货', url: '/orders/123' }));

iOS、Safari 和桌面浏览器有什么差异?

Chrome、Edge、Firefox 支持较成熟,Safari 和 iOS 限制更多。iOS 需要用户把网站添加到主屏幕后才可接收 Web Push,低版本还不支持。踩坑是开发时只在 Chrome 桌面调通,到了 iPhone 上发现根本没有订阅入口。上线前要写清兼容性,不支持的设备用短信、邮件或站内消息兜底。

通知点击和频率怎么设计?

notificationclick 应优先复用已有窗口,避免每次点击都打开新标签。频率上要有业务上限,比如营销通知每天不超过一次,交易通知只发关键状态变化。边界是 requireInteraction、震动、声音等能力不能滥用,过强打扰会让用户永久关闭权限。更稳的做法是提供通知偏好设置,让用户选择提醒类型。

标签:PWA