跳转到内容

iOS 主屏 Web 应用中的 notificationclick 事件

发布于

行为实测 2026-10-20,iPhone 16 Pro,iOS 18.6.2 (22G100)A,仪器读数与 BCD 不符

notificationclick 在主屏 Web 应用的 6 次通知点按中都触发了,两种处理器都运行成功。测试于 2026-10-20 在 iPhone 16 Pro、iOS 18.6.2(22G100)上完成;browser-compat-data(BCD)却把这个事件记为 iOS 版 Safari 不支持。

在 iOS 主屏 Web 应用中,用户点按 Service Worker 自己显示的通知时,notificationclick 处理函数是否会运行?用 addEventListener('notificationclick', …) 注册和赋给 self.onnotificationclick 两种方式是否都有效?处理函数能否把应用窗口切到前台?

测试应用是从 Safari 添加到主屏幕的真机实验室测试工具(v1),名为「PWA Lab」。它的 Service Worker(lab-sw-v2,作用域 /lab/device-tests/)装了两个处理函数:一个用 addEventListener 注册,一个赋给 self.onnotificationclick。两个处理函数各自往 IndexedDB 写入带时间戳的记录,用 via 字段区分路径;两者都不调用 event.preventDefault()。

跳转只由监听器负责。它先调用 clients.matchAll({type: "window", includeUncontrolled: true}),找到实验室窗口就对它调用 focus(),找不到才调用 clients.openWindow(),结果随记录一起保存。

按钮 2a 由页面立即调用 registration.showNotification();按钮 2b 给 worker 发一条消息,worker 等 5 s 后调用 self.registration.showNotification()(见 lab.js 和 sw.js)。第 4 次点按用的是 2a,其余五次用的是 2b。没有发送任何推送消息,测试工具没有推送服务器。应用此前已获得通知权限(实验记录 N32)。

一共跑了五种点按情形,都在主屏应用的上下文中:

  • 在主屏幕上点按横幅;
  • 应用在前台时点按横幅;
  • 在通知中心点按通知;
  • 在应用划掉并重新打开之后点按横幅;
  • 在多任务界面划掉应用之后点按横幅,试图走到 clients.openWindow() 路径。

每条记录有两个时间:createdAt 是页面构造通知参数的时间(2b 在 5 s 等待之前),at 是处理函数开始构造记录的时间(在跳转和写入 IndexedDB 之前)。监听器记录还保存了 clients.matchAll() 返回的窗口数和跳转结果。一个 AI 代理会话通过 USB 经 WebKit 远程检查器从应用页面读取累积的记录,共读了四次,分别在第 3、4、5、6 次点按之后(N35、N36、N38、N40);每次读数也能看出是否存在 notificationclose 记录。

需要一台 iPhone,大约十分钟。Web 检查器可以不用,测试页面会自己打印事件日志。

  1. 在 iPhone 的 Safari 中打开 https://openpwa.net/lab/device-tests/,点按分享,选添加到主屏幕,再点添加。
  2. 从图标打开 PWA Lab。在「T7 and T8: notifications」一节点按 1. Request permission,在系统提示中选允许。
  3. 点按 2b. Show in 5 s (then go Home),立即回到主屏幕。横幅出现后点按它。
  4. 回到应用查看事件日志。两条路径都触发时,每次点按会新增一条标为 addEventListener 的记录和一条标为 onnotificationclick property 的记录,监听器记录里写有跳转结果。
  5. 点按 2a. Show notification now,留在应用中,下拉通知中心,在那里点按这条通知。
  6. 在多任务界面关闭应用,再从图标打开,重复第 3 步。
  7. 测试无窗口路径:点按 2b,立即在多任务界面划掉应用,然后点按横幅。结果为「opened new window」说明 clients.openWindow() 运行了;「focused existing window」说明页面仍然存活。
  8. 点按 Copy results as JSON 保存记录。JSON 里有读取时间(collectedAt)和用户代理字符串,但没有设备型号和系统构建号,这两项要到「设置 > 通用 > 关于本机」另外记下。
  • T8 notificationclick 的暴露、处理函数与通知点击(5 分钟)
    测试页 v1:打开测试

在 iOS 18.6.2(22G100)上,两条处理路径在 6 次点按中全部运行,共产生 12 条记录,每次点按两条(仪器读数,A;实验记录 N35、N36、N38、N40)。每次点按时 clients.matchAll() 都返回一个窗口,对它调用 focus() 都成功。没有出现 notificationclose 记录。应用在前台时也会显示横幅(截图或录屏,S;N63)。

点按 情形 createdAt 监听器 at 属性 at 实验记录
1 横幅,主屏幕 08:22:57.000 08:23:07.007 08:23:07.008 N35
2 应用在前台时的横幅 08:23:21.253 08:23:30.533 08:23:30.534 N35、N63
3 主屏幕上的横幅 08:24:38.479 08:24:46.071 08:24:46.072 N35、N63
4 通知中心 08:26:28.601 08:26:49.588 08:26:49.588 N36
5 划掉并重新打开之后 08:28:40.822 08:28:50.048 08:28:50.061 N38
6 点按前已划掉应用 08:43:03.022 08:43:09.236 08:43:09.245 N40

时间为 2026-10-20 的 UTC。从 createdAt 到 at 的间隔包含操作员的反应时间,2b 的几次点按(除第 4 次外)还包含 5 s 等待,所以不能当作事件派发延迟。每次点按时都有存活的窗口:第 6 次点按时,操作员大约 6 s 前划掉了应用,但上一次重新打开时加载的文档还在,通知点按把它切到了前台(N40)。因此 clients.openWindow() 路径没有走到,这种方法下记为无法运行。

2026-10-20,iOS 18.6.2

在 PWA Lab 主屏应用里,6 次点击(横幅、通知中心、重新启动后、上划关闭后)中 addEventListener 和 self.onnotificationclick 两条路径都触发了 notificationclick,每次对已有窗口调用 focus() 都成功。clients.openWindow() 这条路径没有走到。

日期
2026-10-20
设备
iPhone 16 Pro
系统版本与构建号
iOS 18.6.2 (22G100),正式版
环境
主屏应用
结果
与预期不符
关键数值
  • taps: 6
  • addEventListenerRecords: 6
  • onnotificationclickPropertyRecords: 6
  • focusedExistingWindow: 6
  • notificationcloseRecords: 0
  • openWindowPath: not reached
可信度
A,仪器读数
测试
T8
实验笔记条目
N35, N36, N38, N40
研究
阅读研究 · 数据包
测试页
测试页 v1
使用的测试页 v1 文件(3 个),线上字节的 SHA-256
  • /lab/device-tests/ 42c90845419f5ed3ad15d941bea04f649f4c5d350b1847292292fadd55871486
  • /lab/device-tests/manifest.webmanifest cab4e60719fd1f9c84d04aada2ad6cd937f50615ce646c3ed20f14f0ca09832b
  • /lab/device-tests/sw.js 0e7e6f34cb814d808edba644d664bac0f4337cc59a88dbb509d25a8e11fffc30

BCD 把 api.ServiceWorkerGlobalScope.notificationclick_event 的 safari_ios 记为 version_added: false(ServiceWorkerGlobalScope.json,github.com,2026-10-20 读取)。实测与 BCD 不符。在 2024-04-29 提交、2026-10-20 仍未关闭的 mdn/browser-compat-data#22959(github.com)中,一位 BCD 贡献者解释说,采集器在 Service Worker 中求值 "onnotificationclick" in self,这一检查在 iOS 16、17、18 的 Safari 上都失败。采集器的 worker 由 Safari 标签页控制。在 18.6.2 上,这种上下文里该属性不存在,而且标签页没有 Notification 接口,根本显示不了可以点按的通知(见 worker 事件处理属性的暴露)。这条记录对它所测的上下文是对的,只是推广到了整个 iOS 版 Safari。同一个 BCD 文件已经给 push_event 加了备注「Notifications are supported in web apps saved to the home screen」。同一个 issue 里有参与者报告该事件在 iOS 18 的已安装应用中会触发;本次运行用一份有日期的测量确认了这一报告,不是新发现。

WebKit 268797 号缺陷「notificationclick events in serviceworkers not firing」于 2024-02-05 针对 iOS 17 提交,状态为 NEW,最后修改于 2026-10-12(Bug 268797,bugs.webkit.org)。其中的报告涉及多种应用状态。评论 35(iOS 18.7)指出,用户点按推送通知时若应用没有存活页面,就会丢失点按事件;评论 40(iOS 26.6.2)描述的是另一种规律。本次运行没有发送推送消息,每次点按时都有窗口存活,所以既不能确认也不能否定这个缺陷。

Notifications API 标准把 notificationclick 定义为 Service Worker 事件(Notifications API,whatwg.org),Service Workers 规范定义了 clients.openWindow()(Service Workers,w3.org)。MDN 的 notificationclick 事件页面(developer.mozilla.org)给出的也是测试工具所用的写法:先 matchAll(),再 focus() 或 openWindow()。

脱敏后的证据在研究的数据包中(CC BY 4.0)。事件记录分别在 raw/2026-10-20-ios18.6.2-step22-app-lab-events.json(第 1 至 3 次点按,N35)、raw/2026-10-20-ios18.6.2-step23-app-lab-events.json(第 4 次,N36)、raw/2026-10-20-ios18.6.2-step24-app-lab-events.json(第 5 次,N38)和 raw/2026-10-20-ios18.6.2-step24b-app-lab-events.json(第 6 次,N40),每个文件都有一个 .meta.json 附带文件,记录 UTC 读取时间和工具哈希。横幅截图为 screenshots/2026-10-20_iphone16pro_ios18.6.2_T8_1a.png 与 …_T8_1b_redacted.png。机器可读的运行记录在 /lab/results.json 中,id 为 notificationclick-in-home-screen-apps/2026-10-20-ios-18.6.2-22g100。

这一结果支撑 iOS 与 iPadOS 上的 Web Push 中关于通知点按的一节,以及 notificationclick 条目里 iOS 版 Safari 单元格上的实测条件。

  • 一台设备、一个版本、一名操作员、一个测试日:iOS 18.6.2(22G100)的 iPhone 16 Pro,没有抹掉重置,装有其他主屏应用和一个 Safari Web 扩展。
  • 只点按了 registration.showNotification() 显示的本地通知。没有投递推送消息,因此没有制造出 WebKit 268797 号缺陷中报告的推送条件。
  • 每次点按时都有窗口存活。没有走到无窗口存活时的 clients.openWindow() 路径。针对这条路径的测试列在路线图上。
  • 只有一个子路径作用域的 worker 脚本,没有通知操作按钮,没有调用 event.preventDefault(),也没有测试 notificationclose。
  • iPadOS、其他 iPhone 机型和其他 iOS 版本都没有测试。

设备操作由 OpenPWA 的一名操作员在 iPhone 16 Pro 上完成。AI 代理会话通过 USB 读取页面状态、记录实验笔记并起草本文;自动门禁和 AI 事实核查做了检查。没有人逐篇审阅。