Notification API 初始化失败主因是浏览器安全策略与用户操作:非HTTPS/localhost环境被静默拒绝,手动阻止后需手动重置权限;Firefox移动版等系统级禁用无法检测,仅能运行时判断permission值。

Notification API 初始化失败的常见原因
调用 Notification.requestPermission() 无反应或直接返回 "denied",通常不是代码写错,而是浏览器策略或用户历史操作导致。Chrome 和 Edge 在非安全上下文(即非 https:// 或 localhost)下会静默拒绝权限请求;Safari 则完全不支持非 https 环境下的 Notification API。
- 必须确保页面运行在
https://或http://localhost(含端口,如http://localhost:3000) - 用户曾手动点击过「阻止通知」,后续即使刷新页面也不会再弹出授权框——需引导用户到浏览器地址栏右侧手动重置权限
- 部分浏览器(如 Firefox 移动版)默认禁用通知,且不提供 JS 接口检测是否“被系统级关闭”,只能靠
Notification.permission === "granted"做运行时判断
如何避免重复显示相同通知
同一时刻多个 new Notification() 调用容易造成堆叠、遮挡甚至崩溃(尤其在低配 Android WebView 中)。浏览器本身不自动去重,必须由业务层控制。
- 使用
Notification.close()主动关闭旧通知,但要注意:它只对当前 JS 上下文中仍持有引用的通知有效;页面刷新后引用丢失,无法关闭已显示的通知 - 推荐方案是用唯一
tag参数标识逻辑上同一类消息:new Notification("新订单", { tag: "order_12345" })。相同tag的新通知会自动替换旧通知(仅限同源、同标签) - 不要依赖
timestamp或data字段做去重——它们不影响显示逻辑,也不触发替换行为
Service Worker 中发送通知的必要条件
想在页面关闭后仍能推送通知(比如后台接收 WebSocket 消息),必须通过 service worker 触发 self.registration.showNotification()。但这不是加个文件就能跑通的事。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- Service Worker 文件必须注册在根路径(如
/sw.js),且其作用域(scope)需覆盖发送通知的页面(注册时传{ scope: '/' }最稳妥) -
showNotification()只能在push事件或notificationclick事件中调用;在fetch或定时器里直接调用会报"Failed to execute 'showNotification' on 'ServiceWorkerRegistration'" - 若使用 Firebase Cloud Messaging(FCM),注意 v1 API 返回的
pushPayload默认不含notification字段,需显式配置webpush.notification才能触发 UI 展示,否则只触发push事件但不弹窗
移动端 WebView 中 Notification API 的兼容性陷阱
很多 Hybrid App 以为注入了 Chrome 内核就支持通知,结果发现 Notification 是 undefined 或 permission 永远为 "denied"。
立即学习“前端免费学习笔记(深入)”;
- Android WebView 默认禁用通知权限,需原生层调用
WebSettings.setNotificationEnabled(true)(API 33+)并申请POST_NOTIFICATIONS运行时权限 - iOS WKWebView 完全不支持 Notification API,任何调用都会静默失败;必须走原生通知通道(UNUserNotificationCenter),JS 层只能通过
webkit.messageHandlers触发桥接 - 即使启用成功,部分国产 WebView(如 QQ 浏览器内核、微信 X5)会拦截所有
showNotification调用,且不抛错——建议用if ('Notification' in window && Notification.permission === 'granted')+ 实际发送测试通知并监听onshow事件来双重验证可用性
tag 去重,如果 service worker 没对 event.data.json().id 做缓存判重,仍可能触发两次 showNotification ——而第二次会因 tag 相同而覆盖第一次,导致用户错过首条通知的关键内容。


















