notification.requestpermission() 必须由用户真实交互触发,自动调用(如onload)会被浏览器直接拒绝返回”denied”;需https环境、合法icon路径,且ios safari完全不支持。

Notification.requestPermission() 为什么总被拒绝?
浏览器会直接拒掉自动触发的权限请求——哪怕你写在 window.onload 或 DOMContentLoaded 里,chrome 就当没看见,默默返回 "denied"。
- 必须由用户真实交互触发,比如点击按钮、切换开关、提交表单
- 不能在页面加载完成时立刻调用,也不能用
setTimeout假装“等一会儿” - firefox 某些版本会把
"default"错判成"denied",所以别只靠Notification.permission判断,得真正调一次requestPermission()再看结果 - 首次请求后,用户选“禁止”,之后再调
requestPermission()不会弹窗,也不会改状态,只能引导用户手动去浏览器设置里开
new Notification() 创建通知但没弹出来?检查这几点
不是代码写错,而是环境或参数卡住了。最常见的是:https 缺失、图标路径不合法、权限其实没拿到。
-
Notification只能在 HTTPS 或localhost下工作,HTTP 站点直接静默失败 -
icon参数必须是 HTTPS 路径或 data URL;HTTP 协议下的图片地址,Chrome 会直接丢弃,不报错也不显示图标 - 即使权限是
"granted",如果页面被完全卸载(比如用户关了标签页),new Notification()仍会失败,且无提示 -
body字段几乎所有浏览器都支持,但badge、silent、image在桌面端基本无效或被忽略
用户点了“禁止”,还能提醒吗?
不能发桌面通知,但可以降级——别让功能彻底消失。
- 检测到
permission === "denied"时,立刻 fallback 到alert()或页面内 Toast 提示 - 用
document.title闪烁也是一种可行方案,尤其适合聊天类页面:监听window.onblur后定时切标题文字,用户切回来再恢复 - iOS Safari 完全不支持
NotificationAPI,连"Notification" in window都是false,必须提前判断并走其他路径
通知点击后跳转页面,为什么有时没反应?
onclick 事件能触发,但 window.open() 或 window.focus() 可能被浏览器拦截,尤其是页面不在前台时。
立即学习“前端免费学习笔记(深入)”;
- 确保
onclick回调里先调this.close(),再执行跳转,否则通知框可能残留 -
window.open()在非用户主动触发上下文中会被屏蔽,更稳妥的做法是用window.location.href = "...";跳转当前页 - 如果目标是唤起已打开的标签页,
window.focus()仅在同源且未被关闭时有效;跨域或已被关掉,就只能新开 -
tag参数很重要:相同tag的新通知会替换旧的,避免重复弹窗,也方便后续用getNotifications()管理(不过该方法兼容性差,慎用)
实际用起来,最难的不是写那几行代码,而是把“用户是否真点了允许”这件事,从假设变成可验证的状态。很多人卡在第一步,后面全白搭。