Notification.requestPermission()返回Promise,resolve值为字符串"granted"、"denied"或"default",需用await或.then()处理,非布尔值且必须由用户手势触发。

Notification.requestPermission 会返回什么值
调用 Notification.requestPermission() 后,它会返回一个 Promise,resolve 的值是字符串:"granted"、"denied" 或 "default"。注意:不是布尔值,也不是立即返回,必须用 await 或 .then() 处理。
其中 "default" 表示用户还没做选择(比如关掉弹窗、切走页面),此时权限状态仍是未决定;"denied" 是明确拒绝,后续再调用也不会触发新弹窗;"granted" 才能真正发通知。
- 不能在页面加载完成前就调用 —— 必须由用户手势(如点击按钮)触发,否则 Chrome/Firefox 会静默拒绝并返回
"denied" - 不能在 iframe 中调用(除非主文档已获权限且 iframe 显式声明
allow="notifications") - HTTP 环境下无法使用,必须是 HTTPS 或
localhost(包括127.0.0.1)
为什么点击按钮后没弹出授权弹窗
最常见的原因是触发时机不对。浏览器只允许在“用户激活”(user activation)上下文中发起请求,比如 click、keydown(且有按键输入)、touchstart 等事件处理函数内调用。放在 setTimeout、fetch 回调或 DOMContentLoaded 里都会失败。
示例错误写法:
立即学习“前端免费学习笔记(深入)”;
document.addEventListener('DOMContentLoaded', () => {
Notification.requestPermission(); // ❌ 静默失败
});
正确写法:
button.addEventListener('click', async () => {
const permission = await Notification.requestPermission();
if (permission === 'granted') {
new Notification('Hello');
}
});
如何判断当前是否已有权限
别每次都调用 requestPermission(),先查 Notification.permission 状态:
-
"granted":可直接发通知 -
"denied":不能重试,建议隐藏通知开关或提示“需手动在浏览器设置中开启” -
"default":尚未请求过,可以显示引导文案 + 按钮,等用户点再调用
注意:这个值是同步读取的,但不反映实时变化(比如用户刚在系统设置里关掉权限,这里不会立刻变)。刷新页面后才会更新。
检查逻辑建议写成:
if (Notification.permission === 'granted') {
showNotification();
} else if (Notification.permission !== 'denied') {
// 只有非 denied 才尝试请求,避免无意义弹窗
requestPermission();
}
发通知时提示“Failed to construct 'Notification': Permission denied”
这个错误说明你跳过了权限检查,直接执行了 new Notification(...)。只要 Notification.permission !== 'granted',构造就会抛出该异常。
必须前置校验:
if (Notification.permission === 'granted') {
new Notification('Title', { body: 'Content' });
} else if (Notification.permission === 'default') {
// 这里应该先 requestPermission(),等 resolve 再发
} else {
// permission === 'denied',不发,也不报错
}
另外注意:Safari 对 Notification 支持有限(仅 macOS 10.9+ 且需用户在系统偏好中启用 Safari 通知),iOS Safari 完全不支持。不要依赖它做关键功能路径。
权限本身是按源(origin)存储的,同一域名下所有页面共享状态;但桌面通知内容和行为(如点击跳转)需要自己用 onclick 事件处理,浏览器不会自动打开链接。



















