Notification API 需同时满足 HTTPS(或 localhost)与用户显式授权,否则静默失败;须先检测支持性与权限状态,权限请求必须由用户交互触发,且需正确处理 Promise;参数如 icon 必须为绝对 URL,tag 用于去重,requireInteraction 和 badge 存在平台兼容限制;onclick 回调依赖页面可见性,冻结或后台标签页下不执行。

必须满足 HTTPS(或 localhost) + 用户显式授权两个硬性条件,否则 Notification 构造函数静默失败,连错误都不会抛。
检查支持与权限状态是否可用
别直接调用 new Notification(),先确认环境是否允许:
-
'Notification' in window为false表示浏览器根本不支持(如 iOS Safari) -
Notification.permission返回"granted"才能发;"default"表示还没问过用户;"denied"表示已拒绝,且无法再次弹窗请求(除非用户手动进浏览器设置重置) - HTTP 协议页、
file://本地文件、非localhost的开发环境,NotificationAPI 直接不可用——Chrome 91+ 尤其严格
必须绑定用户交互事件发起 requestPermission()
在页面加载完成时自动调用 Notification.requestPermission() 会被 Chrome 拦截(尤其 91+ 版本),必须由真实用户操作触发:
- 推荐用
button或设置页开关绑定click事件 - 必须用
await或.then()处理返回的 Promise,不能靠setTimeout猜结果 - 首次调用后,权限状态会持久化到该域名下,后续访问可直接检查
Notification.permission === 'granted'
button.addEventListener('click', async () => {
if (Notification.permission === 'granted') {
new Notification('Hi', { body: 'Ready!' });
} else if (Notification.permission === 'default') {
const result = await Notification.requestPermission();
if (result === 'granted') {
new Notification('Hi', { body: 'Thanks!' });
}
}
});
new Notification() 的参数陷阱与兼容要点
title 是必填字符串,options 中几个字段行为差异大,容易踩坑:
立即学习“前端免费学习笔记(深入)”;
-
icon必须是绝对 URL(如https://yoursite.com/icon.png),相对路径在部分浏览器中解析失败 -
tag用于去重:相同tag的新通知会替换旧通知,避免刷屏;不设则每次都是独立通知 -
requireInteraction: true可阻止自动关闭,但桌面 Chrome 会常驻托盘,iOS 完全不支持 -
badge仅在 Android WebView 和 PWA 中生效,桌面 Chrome 忽略 - 没有配置显示时长的参数,系统决定超时逻辑,无法干预
notification.onclick 不执行?看页面是否“活着”
notification.onclick 回调运行在当前页面上下文中,不是 Service Worker,所以有严格限制:
- 页面必须处于可见状态(未被冻结、未被后台标签页休眠)
- 若用户从其他应用切换回来,页面可能已被浏览器冻结,此时点击通知不会触发回调
- 想保证点击响应,需配合
visibilitychange监听并提前激活页面,或改用 Service Worker + Push API 实现离线场景
真正难的不是写几行代码,而是把权限时机、页面生命周期、跨平台兼容这三件事对齐——漏掉任一环,通知就只在你本地控制台里“成功”了。



















