跳转到内容

iOS 标签页与主屏应用中的 Service Worker 事件处理器

发布于

行为实测 2026-10-20,iPhone 16 Pro,iOS 18.6.2 (22G100)A,仪器读数补充条件

同一个 Service Worker 脚本,在 iOS 的 Safari 标签页和主屏应用中暴露的通知、推送成员不同。2026-10-20,我们在 iPhone 16 Pro、iOS 18.6.2(22G100)上读取 'onnotificationclick' in self,标签页一侧为 false,应用一侧为 true。这正是 browser-compat-data(BCD)检测 notificationclick 的表达式。

在 iOS 上,Service Worker 由 Safari 标签页控制时,和由主屏 Web 应用控制时,是否都暴露 onnotificationclick、onpush、Notification,以及注册对象上的 showNotification 与 pushManager?

同一个 worker 脚本 lab-sw-v2(/lab/device-tests/sw.js,作用域 /lab/device-tests/)在两种上下文中读取:

  • 在 Safari 中,用 WebDriver 自动化窗口打开 /lab/device-tests/,页面注册了 worker 并受其控制(实验记录 N03)。自动化窗口有自己的空网站数据存储;特性检测与存储的数据无关。
  • 把同一页面添加到主屏幕,名为「PWA Lab」,再从图标打开。授予通知权限前读一次(N18),授予权限并建立推送订阅后再读一次(N34)。

页面给 worker 发一条探测消息,再把回复打印出来。按线上的 worker 脚本(sw.js),回复分两部分:

  • 在 worker 脚本首次运行、尚未给 self.onnotificationclick 赋值时读取一次(避免赋值操作自己创建要检测的属性):'onnotificationclick' in self、typeof self.onnotificationclick、'onnotificationclose' in self、'onpush' in self 和 'onpushsubscriptionchange' in self;
  • 收到探测消息时读取:'Notification' in self、'showNotification' in registration、'pushManager' in registration 和 typeof clients.openWindow。

标签页和应用两侧用的是同一个页面,不需要 Web 检查器。

  1. 在 iPhone 的 Safari 中打开 https://openpwa.net/lab/device-tests/,等上下文一行显示有 Service Worker 在控制页面。
  2. 在「T7 and T8: notifications」一节点按 Probe worker exposure,记下打印出的每个值。
  3. 点按分享,选添加到主屏幕,再点添加。从图标打开 PWA Lab。
  4. 再次点按 Probe worker exposure,比较两组值。
  5. 可选:点按 1. Request permission 并允许,再探测一次,看权限是否改变应用一侧的值。
  6. 在两种上下文中各点按一次 Copy results as JSON,把值连同时间和用户代理字符串一起保存;JSON 里的用户代理字符串带有系统版本,但没有单独的版本字段,也没有构建号,构建号需要另外到「设置 > 通用 > 关于本机」记下。
  • T8 notificationclick 的暴露、处理函数与通知点击(5 分钟)
    测试页 v1:打开测试

在 iOS 18.6.2(22G100)上,表中的通知与推送成员,在 worker 由 Safari 标签页控制时都不存在,由主屏应用控制时都存在(仪器读数,A;实验记录 N03、N18、N34)。在应用中,授予权限之前这些成员就已存在(N18),授权后的探测返回相同的值(N34),可见这些成员的暴露不需要先授权。

表达式 由 Safari 标签页控制的 worker(N03) 由主屏应用控制的 worker(N18、N34)
'onnotificationclick' in self false true
typeof self.onnotificationclick undefined object
'onnotificationclose' in self false true
'onpush' in self false true
'onpushsubscriptionchange' in self false true
'Notification' in self false true
'showNotification' in registration false true
'pushManager' in registration false true
typeof clients.openWindow function function

在应用上下文中,notificationclick 处理函数在 6 次点按中全部运行,见 iOS 主屏 Web 应用中的 notificationclick 事件。

2026-10-20,iOS 18.6.2

lab 的 service worker(lab-sw-v2)由主屏应用控制时,'onnotificationclick' in self、onpush、Notification 和 registration.showNotification 都存在;同一个 worker 由 Safari 标签页控制时,这些全都不存在。clients.openWindow 在两种情况下都是函数。

日期
2026-10-20
设备
iPhone 16 Pro
系统版本与构建号
iOS 18.6.2 (22G100),正式版
环境
Safari 标签页和主屏应用
结果
与预期不符
关键数值
  • appOnnotificationclickInSelf: true
  • tabOnnotificationclickInSelf: false
  • appTypeofOnnotificationclick: object
  • appNotificationInSelf: true
  • tabNotificationInSelf: false
  • clientsOpenWindow: function
可信度
A,仪器读数
测试
T8
实验笔记条目
N03, N18, N34
研究
阅读研究 · 数据包
测试页
测试页 v1
使用的测试页 v1 文件(2 个),线上字节的 SHA-256
  • /lab/device-tests/ 42c90845419f5ed3ad15d941bea04f649f4c5d350b1847292292fadd55871486
  • /lab/device-tests/sw.js 0e7e6f34cb814d808edba644d664bac0f4337cc59a88dbb509d25a8e11fffc30

BCD 把 api.ServiceWorkerGlobalScope.notificationclick_event 的 safari_ios 记为 version_added: false(ServiceWorkerGlobalScope.json,github.com,2026-10-20 读取)。在 mdn/browser-compat-data#22959(github.com)中,一位 BCD 贡献者说明:采集器在 Service Worker 中求值 "onnotificationclick" in self 来检测这一特性,该检查在 iOS 16、17、18 的 Safari 上都失败,而这个属性受一个 WebKit 偏好设置控制。本次测量给这条记录补充条件:worker 由 Safari 标签页控制时检查为 false,由主屏应用控制时为 true。如果采集器是在浏览器标签页中运行检查,这就能解释它得到的 false;该 issue 没有说明采集器用的是哪种上下文。

WebKit 的 iOS 16.4 文章把 Web Push 与通知限定在添加到主屏幕的 Web 应用(Web Push for Web Apps on iOS and iPadOS,webkit.org),同一个 BCD 文件也给 push_event 加了备注「Notifications are supported in web apps saved to the home screen」。两者都没有说 worker 自身的成员会随控制上下文而不同。WebKit 252625 号缺陷「NotificationEvent interface exists but Notification interface does not on iOS 16.4」已解决(Bug 252625,bugs.webkit.org),说明这个平台上的接口暴露以前就出现过不一致。Notifications API 标准在 ServiceWorkerGlobalScope 上定义了 onnotificationclick 与 onnotificationclose(Notifications API,whatwg.org),没有附加上下文条件。

前期检索没有找到按控制上下文区分这些成员的公开记录。

这些值在研究的数据包中(CC BY 4.0):标签页一侧在 raw/2026-10-20-ios18.6.2-tab-lab.json(N03),应用一侧授权前在 raw/2026-10-20-ios18.6.2-step12-app-lab.json(N18),授权后在 raw/2026-10-20-ios18.6.2-step21-app-lab-exposure.json(N34)。应用一侧的文件都有一个 .meta.json 附带文件,记录 UTC 读取时间、工具哈希和所选页面。机器可读的运行记录在 /lab/results.json 中,id 为 worker-event-handler-exposure-tab-vs-app/2026-10-20-ios-18.6.2-22g100。

这一结果支撑 iOS 与 iPadOS 上的 Web Push 对 BCD notificationclick 记录的解释,以及 Web Push 兼容性数据中 iOS 版 Safari 一行的主屏条件。

  • 一台设备、一个版本、一名操作员、一个测试日:iOS 18.6.2(22G100)的 iPhone 16 Pro,没有抹掉重置。
  • 标签页一侧的读数来自 WebDriver 自动化窗口,它有自己的空数据存储。设备上装有一个身份不明的 Safari Web 扩展,运行在 Safari 的进程中,可能影响标签页一侧的读数。
  • 标签页和应用各自注册了同一个脚本;这里比较的是上下文,不是同一个 worker 实例。
  • 只读取了表中的成员。对四个事件处理器属性的五项检测只在 worker 脚本启动时做一次,所以授权后的探测重复的是那次启动时的值;记录无法说明其间 worker 是否重启过。WebKit 功能标志可能改变这些值,本次运行没有记录设备的功能标志状态。
  • iPadOS、macOS 上的 Safari 和其他 iOS 版本都没有测试。同一台设备升级到 iOS 27 后会重新测试。

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