渐进式 Web 应用依赖 Web Push API 与 Service Worker 来重新触达用户——购物车提醒、突发新闻、打车通知、两步验证码。这条链路,恰恰是 WebView 里不存在的东西。Android WebView 没有 Push API,也没有后台执行能力;苹果自己的 DTS 工程师明确表态,任何使用 WKWebView 的 App 都无法使用 Web Push。授权弹窗永不出现,订阅静默失败,H5 原本设计要发出的每一条再营销消息都石沉大海。宿主自有 runtime 用原生推送桥把它补回来——设备上走 FCM 或 APNs,用 JS 桥注册令牌,对页面而言与 Web 标准完全一致。
Android:没有 Push API,也没有后台唤醒
Android 官方文档与开发生态一致认定:WebView 只是渲染组件,不是完整浏览器。它不实现 Push API,不会为推送保活 Service Worker,App 关闭时更无法被唤醒接收任何消息。试图把 Web Push 与 WebView 硬凑在一起的开发者最终都得出同一结论——单靠 WebView 不可能;变通方案是下沉到原生层的 Firebase Cloud Messaging,再通过 JavaScript 桥把载荷推过去。这是实打实的工程量:消息服务、通知渠道、令牌同步流程——而一个裸 WebView 根本不提供这些。
iOS:平台直接说不
iOS 上情况更尖锐。WebView 页面在某些配置下(app-bound domains 或浏览器授权)能注册 Service Worker,但 Web Push 本身不可用。在苹果开发者论坛里,苹果 DTS 工程师直截了当地回答:「Web Push 通知无法在使用 WKWebView 的 App 中工作。你可以在同时带有 WKWebView 的 App 里使用原生推送,但不是 Web Push。」同一个页面在 Safari 里是干净的订阅按钮,在内嵌视图里却什么都不显示——没有弹窗,没有报错,只有沉默。
没有推送通道,你会失去什么
- 订阅按钮变死钮。 弹窗永不出现,本想授权的用户根本没机会点。
- 再营销全丢。 弃购提醒、物流更新、新闻推送——PWA 投入推送的全部理由——一条都到不了。
- 身份再次割裂。 用户在系统浏览器里登录过的 H5,到了 App 的 WebView 里是陌生人,推送也补不上这道裂缝。
- 静默分歧。 同一段代码在 Chrome 和 Safari 里订阅正常,在 WebView 里静默空转。
- 没有后台同步。 Service Worker 驱动的后台同步与定时拉取不可用,离线写后队列直接卡死。
runtime 解法
宿主自有 runtime 在页面之下提供一条原生推送桥:用 FCM 或 APNs 在设备层注册,暴露一组极小的 JS API(请求授权、获取令牌、接收载荷),镜像 Web 的 Push API,并在点击时把通知路由到正确的应用内页面。H5 作者写的是同一套订阅流程;runtime 补上 WebView 缺失的通道,双端一致,只有一个契约。
| 维度 | WebView | 宿主自有 runtime |
|---|---|---|
| Push API | 未实现 | 原生桥(FCM/APNs) |
| 授权弹窗 | 永不出现 | 原生弹窗,镜像到 JS |
| 后台唤醒 | App 关闭时不可能 | 操作系统级送达 |
| Service Worker 推送 | 不支持 | 桥接到原生 |
| 再营销 | 丢失 | 恢复 |
| 跨端契约 | 无 | 一套 API,双端通用 |
浏览器把订阅按钮视为「将来会收到消息」的承诺;裸 WebView 把它当成可以随意忽略的请求。runtime 守住这个承诺——一条推送通道,在设备层是原生,对页面而言是 Web 形态。
参考来源
- Apple 开发者论坛 — 使用 WKWebView 的 App 无法使用 Web Push(DTS 工程师确认) — 平台级定论。
- Stack Overflow — Android WebView 不支持 Push API — 缺失的 API。
- MDN — Push API 参考 — WebView 所缺的 Web 标准。
- web.dev — Push 通知概览 — 这条链路本应如何运作。
- MDN — Service Worker API — WebView 无法为推送保活的后台脚本。