跳转到内容

通知 · API

Notification.requestPermission()

发布于 更新于

有限可用不支持的浏览器: Safari (iOS)、WebView (Android)WHATWG 现行标准

Notification.requestPermission() 询问用户是否允许该源显示系统通知,并以结果状态兑现;Notification.permission 随时读取该状态而不弹窗。同一个权限也把关 ServiceWorkerRegistration.showNotification(),并且因为推送订阅需要它,也把关 PushManager.subscribe(),所以这一个提示是 PWA 所有通知路径的闸门。

Notification.requestPermission()
Notification.permission

requestPermission() 是静态方法,返回 Promise<NotificationPermission>,字符串取值为 "default"、"granted" 或 "denied"。它还接受一个旧式回调参数 Notification.requestPermission(callback),这是 Safari 15 之前唯一支持的形式(BCD api.Notification.requestPermission_static)。Notification.permission 是只读静态属性,取值相同。两者都只存在于窗口中;worker 没有 Notification.requestPermission,Service Worker 通过 registration.pushManager.permissionState() 或 navigator.permissions.query({ name: 'notifications' }) 读取状态。

参数 类型 含义
deprecatedCallback function,可选 用户做出决定时以权限字符串调用。为兼容 Safari 7 至 14 保留;新代码直接等待 Promise。

三个权限值并不对称。"default" 表示用户尚未决定,浏览器按 "denied" 处理;"denied" 表示用户或企业策略已拒绝,直到用户更改站点设置之前不会再弹出提示;"granted" 是唯一能让 showNotification() 成功的状态。

requestPermission() 不会因拒绝而抛出,而是以 "denied" 兑现。下面的失败都发生在提示之前。

失败 位置 触发条件
ReferenceError 读取 Notification iOS 与 iPadOS 上的 Safari 不定义该接口,除非页面作为 manifest 设置了非默认 display 的主屏幕 Web App 运行(BCD 对 api.Notification 的备注)。访问静态成员之前先测试 'Notification' in window。
不弹提示直接兑现 "denied",并打出控制台信息 Firefox 72+ 调用不在用户产生的事件处理函数内。Firefox 记录 The Notification permission may only be requested from inside a short running user-generated event handler.(dom.properties 中的 NotificationsRequireUserGesture,github.com)。
不弹提示直接兑现 "denied",并打出控制台信息 Firefox 70+ 调用来自跨源 <iframe>:The Notification permission may only be requested in a top-level document or same-origin iframe.
不弹提示直接兑现 "denied",并打出控制台信息 Firefox 页面不是安全上下文:The Notification permission may only be requested in a secure context.
提示被抑制,状态停留在 "default" Chrome 80+ Chrome 的静默权限界面用地址栏里一个带斜线的铃铛图标替代弹窗,针对习惯拒绝通知的用户和接受率低的站点(Introducing quieter permission UI for notifications,blog.chromium.org);Promise 只在用户点击图标并做出选择后才兑现。

macOS 上的 Safari 同样要求用户手势,否则不弹提示直接兑现 "denied"。

示例把「询问」(一次,来自手势)和「读取」(每次加载)分开,最后给出无法显示系统通知的平台的兜底。

请求在 click 处理函数内运行,满足 Firefox 72 与 Safari 的要求。拒绝后按钮仍然可见,用户可以更改站点设置后再试。

const button = document.querySelector('#enable-alerts');
button.addEventListener('click', async () => {
const state = await Notification.requestPermission();
if (state === 'granted') {
button.hidden = true;
await showWelcomeNotification();
} else {
button.textContent = '通知已在浏览器设置中被拦截';
}
});

不要在加载时或定时器里调用 requestPermission():Firefox 会带着上面的控制台信息兑现 "denied",而 Chrome 和 Safari 会按站点记住这次拒绝。

Notification.permission 是同步的且不会弹窗,所以它是决定是否渲染「启用」按钮的正确检查。Permissions API 以异步方式给出同样的答案,而且在 Service Worker 内也能用。

function notificationState() {
if (!('Notification' in window)) return 'unsupported';
return Notification.permission; // "default" | "granted" | "denied"
}
async function notificationStateInWorker() {
const status = await navigator.permissions.query({ name: 'notifications' });
return status.state; // "prompt" | "granted" | "denied"
}

Permissions API 把未决定状态写作 "prompt",Notification.permission 写作 "default",两个词是同一个意思。

iOS 浏览器标签页里没有该接口,Android WebView 里完全没有,而在任何平台上用户都可能已经拒绝。一个函数覆盖三种情况,返回一个应用其余部分可以调用的通知器。

async function getNotifier() {
if (!('Notification' in window) || !('serviceWorker' in navigator)) {
return showInPageToast; // 这里没有系统通知:在页面内渲染
}
if (Notification.permission !== 'granted') {
return showInPageToast; // 未决定或已拒绝:不要在这里弹提示
}
const registration = await navigator.serviceWorker.getRegistration();
if (!registration?.active) return showInPageToast;
return (title, body) => registration.showNotification(title, { body });
}

页内 toast 是每个分支的兜底,所以无论平台给出什么答案,调用方都只面对一个签名。

规范

规范状态
Notification.permission / requestPermission()(通知权限)WHATWG 现行标准
  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Desktop)支持32中来源—
Chrome (Android)支持42中来源—
Edge (Desktop)支持14中来源—
Firefox (Desktop)支持22中来源—
Firefox (Android)支持22中来源—
Safari (macOS)支持7中来源—
Safari (iOS)部分支持16.4中来源1
Samsung Internet支持4.0中来源—
WebView (Android)不支持—中来源2
  1. 仅限已添加到主屏幕的 Web 应用;普通浏览器标签页不可用。
  2. 依据 MDN browser-compat-data,不支持。

源数据: /compatibility/notification-permission.json · 全球使用占比: 67 % (StatCounter 2026-05)

来源: 规范 · MDN · 最近核验 2026-09-08 · 置信度: 中 (由来源计算)