GitHub CI通知书签小工具已获Notification权限但通知不弹出的问题排查
故障原因结论
该问题与浏览器沙箱限制无直接关系,是Web Notification API的使用疏漏、现代浏览器安全拦截规则共同导致的,当前出现的「所有console日志正常输出、通知完全不弹出」是这类问题的典型表现。
具体问题点
- 未校验通知权限的实际状态
代码中Notification.requestPermission().then()的回调没有接收权限返回值做有效性判断,默认进入then分支就代表通知权限已授予。实际上如果用户在权限弹窗中选择「拒绝」,或是关闭弹窗保持默认状态,后续直接调用new Notification()会静默失败,不会抛出可感知的报错,这是通知不弹出的常见诱因。 - 触发通知的时机违反浏览器安全规则
现代Chromium内核浏览器对普通页面创建的桌面通知有明确约束:必须在用户完成明确交互后的短时间内创建通知实例,才会正常弹出。你当前的逻辑是点击书签(触发脚本运行)后,通过setInterval轮询等待CI跑完,这个等待过程从数秒到数十秒不等,早已超过浏览器允许的延迟触发窗口,此时在定时器回调里创建的Notification会被直接拦截,不会弹出。 - 定时器清理逻辑不严谨
代码中用setInterval创建的轮询任务,却调用clearTimeout(search)做停止操作。虽然当前主流浏览器对两类定时器的ID池做了兼容,不会直接导致功能异常,但属于逻辑错误,正确清理写法为clearInterval(search)。 - 后台定时器节流影响
长期在页面后台运行的setInterval会被浏览器的后台节流策略降频,就算成功检测到CI状态,也可能因为定时器被节流,让通知创建时机落在拦截窗口外,进一步提升静默失败的概率。
修复方向参考
- 权限判断补充校验:只有当
Notification.permission === 'granted'时才启动轮询逻辑,否则直接在页面提示用户通知权限未开通。 - 若需要延迟触发通知,需改用Service Worker版本的通知接口(通过
ServiceWorkerRegistration.showNotification()调用),这类接口不受“用户交互后立即触发”的时机限制,适配轮询等待的场景。 - 若不想引入Service Worker,可在检测到CI完成后,先在页面内显示醒目提示条,引导用户点击提示条上的按钮触发通知——此时的点击属于新的用户交互,不会被浏览器的通知时机规则拦截。
内容的提问来源于stack exchange,提问作者suddjian
相关产品推荐
相关产品推荐

