notification.requestpermission() 必须由用户手势触发,否则被静默拒绝;需先检查 notification.permission 状态,仅在 'default' 时调用;new notification() 要求 https(localhost 除外),且 icon 等参数有兼容性限制。

Notification.requestPermission() 必须由用户手势触发
浏览器明确禁止页面自动弹出权限请求,否则会被静默拒绝或直接报
DOMException: The request is not allowed</p> <p>常见错误现象:页面一加载就调用 <code>Notification.requestPermission(),控制台显示
NotAllowedError,通知权限始终卡在 default
- 只允许在
click、keydown(且有实际输入)、submit等真实用户交互回调中调用 - 不能包裹在
setTimeout或Promise.then里“绕过”,只要调用栈里没有用户事件上下文,就无效 - 移动端部分浏览器(如 iOS Safari)根本不支持桌面通知,调用后直接返回
denied,不弹窗
检查 Notification.permission 状态再决定是否请求
重复请求或对已拒绝状态强行调用 requestPermission() 不仅无效,还可能触发浏览器警告甚至屏蔽后续提示
使用场景:用户点击“开启提醒”按钮时,先查当前状态,再做对应处理
立即学习“前端免费学习笔记(深入)”;
-
permission === 'granted':可直接调用new Notification() -
permission === 'denied':说明用户点过“拒绝”,此时应引导其手动到浏览器设置页修改(chrome://settings/content/notifications等路径) -
permission === 'default':尚未授权,可安全触发requestPermission()
new Notification() 的 title 和 options 参数要注意兼容性
不是所有字段在所有浏览器都生效,尤其图标路径、重用 tag、silent 等特性容易被忽略导致行为异常
参数差异与坑点:
-
icon必须是 HTTPS 路径(本地开发可用localhost),HTTP 或相对路径在 Chrome 中会静默失败 -
tag用于去重:相同tag的通知会替换而非叠加,但 Firefox 对tag支持不稳定 -
silent: true在 Safari 中无效,且部分安卓 WebView 完全忽略该字段 - 不要传
body为空字符串,某些旧版 Edge 会因此抛错
简短示例:
if (Notification.permission === 'granted') {<br> new Notification('消息标题', {<br> body: '这是内容',<br> icon: '/assets/icon-192.png',<br> tag: 'news-update'<br> });<br>}
HTTPS 是硬性前提,localhost 是唯一例外
Chrome、Firefox、Edge 全部要求页面必须通过 HTTPS(或 localhost)提供服务,否则 Notification 构造函数会直接抛 TypeError: Illegal constructor
性能与部署影响:
- 本地开发用
http://localhost:3000没问题,但http://127.0.0.1:3000或http://mydev.local都不行 - 测试环境若用 HTTP,连
Notification.permission都读不到,始终是undefined - 自签名证书也不行,必须是受信任 CA 签发的 HTTPS
这个限制没法绕过,连 Service Worker 里也无法补救 —— 权限模型绑定的是页面来源协议。











