HTML 本身不能实现通知推送,必须通过 JavaScript 调用浏览器提供的 Notification API,且需用户手势触发权限请求、HTTPS 环境及权限校验后方可发送通知。

HTML 本身不能做通知推送,必须配合 JavaScript 和浏览器 API
HTML 是静态标记语言,不负责行为逻辑。所谓“通知推送”,实际依赖的是 Notification API,它由浏览器提供、JavaScript 调用,且必须在用户主动交互(如点击按钮)后才能请求权限。直接在 HTML 里写个开关标签(比如 <input type="checkbox">)不会触发任何通知能力——它只是个 UI 元素,背后没 JS 绑定就等于摆设。
常见错误现象:Notification.permission 始终返回 "denied" 或 "default",调用 Notification.requestPermission() 没反应,或控制台报错 DOMException: The user denied permission to use Notifications。
- 必须通过 HTTPS(本地
localhost除外),HTTP 页面会被浏览器直接禁用通知 API - 首次调用
Notification.requestPermission()必须由用户手势触发(例如click、touchend),不能在页面加载时自动执行 - Chrome/Edge 等现代浏览器已屏蔽静默授权,
requestPermission()不再支持传入"granted"参数强行绕过
如何实现一个带开关状态的“通知设置”页面
核心是把 UI 开关(checkbox)和 Notification 权限状态双向同步,并确保权限变更后能真实影响后续通知发送逻辑。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 页面加载后立即检查当前权限:
Notification.permission,并用该值初始化 checkbox 的checked状态 - 给 checkbox 绑定
change事件:如果用户勾选但权限不是"granted",则调用Notification.requestPermission();如果取消勾选,则跳过请求,仅更新本地状态(如 localStorage) - 权限请求回调中,根据返回值(
"granted"/"denied")手动同步 checkbox 状态,避免用户误操作导致 UI 和实际权限不一致 - 不要依赖 checkbox 的初始
checked属性值来判断权限,它可能和Notification.permission不一致
示例关键逻辑(非完整页面):
const notifyToggle = document.getElementById("notify-toggle");
notifyToggle.checked = Notification.permission === "granted";
notifyToggle.addEventListener("change", async () => {
if (notifyToggle.checked && Notification.permission !== "granted") {
const result = await Notification.requestPermission();
notifyToggle.checked = result === "granted";
}
});
为什么不能用 form 提交或纯 HTML 属性控制通知
因为通知权限属于浏览器安全上下文的一部分,不由页面 DOM 属性或表单数据决定,而是由 Notification.permission 这个只读属性 + 用户系统级授权记录共同维护。即使你用 localStorage 记录了“用户想开通知”,只要 Notification.permission !== "granted",调用 new Notification(...) 就会静默失败或抛出异常。
容易踩的坑:
- 把开关状态存在
localStorage后就以为“设置生效”,结果用户没授予权限,后续通知全发不出 - 在
requestPermission()后不检查返回值,直接假设成功,导致new Notification()报TypeError: Failed to construct 'Notification': Illegal constructor - 在非安全上下文(HTTP 非 localhost)下调试,始终卡在
"default",却误以为代码有问题
发送通知前必须做的三件事
不是点了开关就能发通知。每次调用 new Notification() 前,必须确认:
-
Notification.permission === "granted"—— 权限已明确授予 - 当前页面处于激活态(
document.hasFocus() === true)或后台运行(部分浏览器允许后台通知,但需 Service Worker 支持) - 没有被浏览器通知设置全局屏蔽(比如 Chrome 设置里关闭了该站点的通知)——这个无法用 JS 检测,只能引导用户去浏览器设置页检查
Service Worker 不是必需项,但如果你需要在页面关闭后仍能推送(比如消息提醒),就必须引入它,且注册流程比普通页面 JS 更严格。纯前端页面能做到的,仅限于用户打开该页面期间、主动触发的通知。


















