跳转到内容

通知 · 概念

iOS 与 iPadOS 上的 Web Push(16.4+)

发布于 更新于

有限可用不支持的浏览器: Safari (iOS)W3C

iOS 与 iPadOS 16.4(2023-03)为添加到主屏幕的 Web App 加入了 Web Push:与桌面端相同的 Push API、Notifications API 与 Service Worker 组合,经 Apple Push Notification service 投递,并且只有在用户安装应用并点按一个请求权限的控件之后才可用。在 iPhone 的 Safari 标签页里 Notification 接口并不存在,所以未安装的站点连「询问」都做不到。

WebKit 把整个特性绑定在安装上。用户从分享菜单选择「添加到主屏幕」且 manifest 的 display 成员为 standalone 或 fullscreen(或 minimal-ui,任何非默认值)时,站点成为主屏幕 Web App;没有这个 manifest 值,图标只是一个在 Safari 中打开的书签,而 Safari 里没有推送(Web Push for Web Apps on iOS and iPadOS,webkit.org)。自 16.4 起第三方浏览器也可以提供同样的分享菜单项,生成的应用无论由哪个浏览器添加都以 Web App 方式打开。

browser-compat-data 把 iOS 上的 Notification 记为 16.4、部分支持,并附两条备注:除非页面是 manifest 带非默认 display 的主屏幕 Web App,否则接口未定义;通知只能由 Service Worker 发出(api.Notification 的 safari_ios)。两条都有代码后果。标签页里的 Notification.requestPermission() 抛出的是 ReferenceError,不是被拒绝的 Promise;new Notification() 在该平台上完全没有可用路径,registration.showNotification() 是显示通知的唯一方式。

在已安装的应用内,权限请求必须跟随直接的用户交互,例如点按订阅按钮;随后 iOS 显示系统通知提示,用户在「设置 > 通知」里按 Web App 管理结果,与原生应用一样。pushManager.subscribe() 要求 userVisibleOnly: true 和 VAPID applicationServerKey;返回的 endpoint 位于 *.push.apple.com 主机上,按白名单放行推送端点的服务器必须允许它。WebKit 会撤销 push 事件没有产生可见通知的订阅(Meet Web Push,webkit.org),所以吞掉消息或在 showNotification() 之前失败的处理函数付出的代价是整个订阅,而不是一条提醒。

通知与「专注模式」集成,manifest id 与用户所取名称相同的 Web App 在多台设备之间同步专注设置。Badging API(navigator.setAppBadge())在同一版本为主屏幕 Web App 发布,通知权限授予后即显示角标。

iOS 与 iPadOS 18.4 为主屏幕 Web App 增加了第二种形态,Safari 18.5 把它带到 macOS:window.pushManager(BCD api.Window.pushManager:Safari 18.4)让页面无需 Service Worker 即可订阅,而符合声明式 JSON 格式("web_push": 8030 加一个 notification 对象)的推送消息由浏览器直接显示,不运行任何 JavaScript。存在 Service Worker 时它仍可修改通知;若其处理函数失败,声明式消息作为兜底显示,所以上述撤销规则在这条路径上不会生效(Meet Declarative Web Push,webkit.org)。

macOS Ventura 上的 Safari 16 最先发布 Web Push(2022-10),通过 webpushd 守护进程投递,Safari 无需运行。iOS 与 iPadOS 16.4 随后跟进,仅限主屏幕 Web App,本页的 compat 表同时跟踪两者。Android WebView 和其他应用内的 iOS WebView 没有推送;Android 上基于 Chromium 的浏览器在任何标签页里都有。

示例在 iOS 上运行于已安装的应用内,在其他平台运行于任意标签页;第一个示例就是区分两者的守卫。

把未安装的 iPhone 访客引导到安装指引

Section titled “把未安装的 iPhone 访客引导到安装指引”

'Notification' in window 这一测试在 iOS 上就是安装检查:标签页里为 false,主屏幕应用里为 true。它在其他平台上也是正确的第一步,所以不需要任何平台嗅探。

async function enablePush(registration, applicationServerKey) {
if (!('Notification' in window)) {
showAddToHomeScreenGuidance(); // iOS 标签页或应用内嵌网页视图:先安装
return null;
}
const permission = await Notification.requestPermission();
if (permission !== 'granted') return null;
return registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey });
}

从点按处理函数里调用 enablePush();在 iOS 上,直接用户交互之外的调用不弹提示直接兑现 "denied"。

在 push 处理函数中兑现 userVisibleOnly 的承诺

Section titled “在 push 处理函数中兑现 userVisibleOnly 的承诺”

每个 push 事件都必须以 showNotification() 结束,包括错误路径,否则 WebKit 撤销订阅。一条通用的兜底通知比什么都不显示更安全。

self.addEventListener('push', (event) => {
event.waitUntil((async () => {
let payload = { title: '有新内容', body: '' };
try {
payload = event.data.json();
} catch {
// 载荷格式错误:仍然要显示点什么,否则订阅会被撤销
}
await self.registration.showNotification(payload.title, { body: payload.body });
})());
});

这里的 try/catch 在 iOS 上比别处更重要:一个发送了错误格式 body 的服务端 bug,否则会悄悄让每一位 iPhone 用户退订。

存在声明式管理器时优先使用它

Section titled “存在声明式管理器时优先使用它”

探测你将要使用的管理器,而不是探测 PushManager 接口。window.pushManager 只在声明式路径上存在;Service Worker 注册上的 pushManager 需要活跃的 worker。

async function getPushManager() {
if ('pushManager' in window) return window.pushManager; // Declarative Web Push,Safari 18.4+
if (!('serviceWorker' in navigator)) return null; // 完全没有推送:只能用应用内消息
const registration = await navigator.serviceWorker.getRegistration();
return registration?.active ? registration.pushManager : null;
}

没有任何注册时 getRegistration() 以 undefined 兑现;navigator.serviceWorker.ready 在这种情况下会永远等待,这正是探测避开它的原因。

规范

规范状态
Web Push(网页推送)W3C
  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Android)支持50中来源—
Chrome (Desktop)支持50中来源—
Edge (Desktop)支持17中来源—
Safari (iOS)部分支持16.4中来源1
Safari (macOS)支持16中来源—
Firefox (Desktop)支持44中来源—
Samsung Internet支持5.0中来源—
  1. 仅限已安装到主屏幕的 Web 应用;需要在用户手势下授权,并通过 APNs 投递 Web Push。

生态与商业政策

主体类型场景状态赞助备注
Apple Push (APNs)delivery_policyiOS部分支持否iOS 上的 Web Push 要求用户先把应用添加到主屏幕。

源数据: /compatibility/web-push.json · 全球使用占比: 89 % (StatCounter 2026-05)

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