Puppeteer Browser.getPWAState():读取已安装 PWA 的 OS 集成状态(徽章计数与文件处理器)
本篇指南聚焦 Puppeteer 的 Browser.getPWAState() 方法:它用于查询一个已安装渐进式 Web 应用(PWA)在操作系统层面的集成状态,包括应用图标上的当前徽章计数(badge count)与应用向 OS 注册的文件处理器(file handlers)。读完本文,你将掌握该方法的签名、参数与返回值结构、"仅限管道(pipe)连接"的使用约束,以及它在 installPWA / launchPWA / uninstallPWA 这套 PWA 生命周期 API 中的位置,并能直接写出可运行的状态查询与验证代码。
方法定位:PWA 生命周期 API 之一
Browser.getPWAState() 是 Puppeteer Browser 类上的抽象方法,定义在 api/Browser.ts:
class Browser {
abstract getPWAState(options: GetPWAStateOptions): Promise<PWAState>;
}
它的职责是:返回一个已安装 PWA 的 OS 集成状态,例如徽章计数和已注册的文件处理器。从源码结构看,它与另外三个 PWA 方法共同构成一组围绕"manifest id"的应用生命周期 API(见 api/Browser.ts):
| 方法 | 作用 | 底层 CDP 命令 |
|---|---|---|
installPWA(options) |
安装一个 Web 应用,返回其 manifest id | PWA.install(可选 PWA.changeAppUserSettings) |
launchPWA(options) |
启动已安装的应用,返回其 Page |
PWA.launch |
uninstallPWA(options) |
卸载应用 | PWA.uninstall |
getPWAState(options) |
查询应用的 OS 集成状态 | PWA.getOsAppState |
其中 installPWA 会返回 manifest id,可直接传给 getPWAState、launchPWA 或 uninstallPWA,因此 getPWAState 的典型输入正是安装时拿到的 id。
参数:GetPWAStateOptions
参数 options 的类型为 GetPWAStateOptions,完整定义见 api/Browser.ts:
| 属性 | 类型 | 说明 |
|---|---|---|
manifestId |
string(必填) |
Web 应用 manifest 文件中的 id |
export interface GetPWAStateOptions {
/**
* The id from the web app's manifest file.
*/
manifestId: string;
}
关于 manifestId 的取值,源码中 InstallPWAOptions.manifestId 的注释给出了更具体的说明(见 api/Browser.ts):"The id from the web app's manifest file, commonly the URL of the site installing the web app."——即 manifest 文件中的 id,常见形态就是安装该 Web 应用的站点 URL。实际开发中最可靠的做法是:先调用 installPWA,把它的返回值作为 manifestId 传递下去。
返回值:PWAState
方法返回 Promise<PWAState>,PWAState 接口定义见 api/Browser.ts:
| 属性 | 类型 | 说明 |
|---|---|---|
badgeCount |
number |
当前显示在应用图标上的徽章计数 |
fileHandlers |
Protocol.PWA.FileHandler[] |
应用向操作系统注册的文件处理器列表 |
export interface PWAState {
/**
* The current badge count shown on the app icon.
*/
badgeCount: number;
/**
* The file handlers registered by the app with the OS.
*/
fileHandlers: Protocol.PWA.FileHandler[];
}
两个字段对应的是 Chromium 侧"应用已安装到桌面/OS 后"的集成数据:badgeCount 反映未读数类标记,fileHandlers 反映 manifest 中声明、并由浏览器登记到系统的文件类型处理项。fileHandlers 的元素类型直接复用 CDP 协议定义 Protocol.PWA.FileHandler,因此其具体字段随 Chromium 协议版本演进。
使用约束:三条硬性限制
官方文档(见 docs/api/puppeteer.browser.getpwastate.md)的 Remarks 与源码共同划定了三条边界:
- 仅在管道连接下可用。Puppeteer 默认通过 WebSocket 连接浏览器;PWA 相关的 CDP 域(
PWA)只在 pipe 连接下提供。要在本地启动时启用 pipe,需在启动选项中显式设置,见 node/LaunchOptions.ts 中pipe选项的说明:"Connect to a browser over a pipe instead of a WebSocket."。 - 只对已安装的应用有意义。文档明确注明:"Meaningful only for an app that is currently installed; querying an unknown manifest id rejects." 即查询一个未安装(或已卸载)应用的 manifest id 时,Promise 会 reject。
- 配置了网络限制时直接抛错。CDP 实现里对每个 PWA 方法都有同一个前置检查(见 cdp/Browser.ts):若浏览器配置了网络限制,调用会抛出
'PWA APIs are not supported when network restrictions are configured.'。这一点有测试用例直接验证:network_restrictions.test.ts 中 "PWA validation" 一节断言installPWA、launchPWA、uninstallPWA、getPWAState在该场景下均抛出同一错误信息。
源码级实现:一次 CDP 命令的透传
CDP 实现位于 cdp/Browser.ts,逻辑非常直接:
override async getPWAState(options: GetPWAStateOptions): Promise<PWAState> {
if (this.#hasNetworkRestrictions) {
throw new Error(
'PWA APIs are not supported when network restrictions are configured.',
);
}
const {badgeCount, fileHandlers} = await this.#connection.send(
'PWA.getOsAppState',
{manifestId: options.manifestId},
);
return {badgeCount, fileHandlers};
}
可以读出三点实现事实:
- 方法在浏览器级 CDP 会话(
this.#connection)上直接发送PWA.getOsAppState,不依赖任何页面或目标,这与installPWA发送PWA.install、launchPWA发送PWA.launch的模式一致(见 cdp/Browser.ts); - 协议返回的
badgeCount、fileHandlers字段被原样解构并组装成PWAState返回,无额外变换; - 网络限制检查发生在协议调用之前,属于快速失败。
与 launchPWA 相比,getPWAState 的实现没有任何 target 解析逻辑(launchPWA 需要把 PWA.launch 返回的 tab target 解析为其子 page target),因此它是这组 API 中调用路径最短、也最适合作为"安装后断言"使用的方法。
实战:安装、查询、启动、卸载的完整链路
下面的示例把 getPWAState 放进完整的 PWA 生命周期中,流程与仓库集成测试 pwa.test.ts 保持一致。注意 pwa.test.ts 开头注明:The PWA CDP domain is only available over a pipe connection。
import puppeteer from 'puppeteer';
// 必须用 pipe 连接启动,PWA 域才可用
const browser = await puppeteer.launch({pipe: true});
const manifestId = 'https://example.com/'; // 与 manifest 中的 id 一致
// 1. 安装(installPWA 返回 manifestId,可传递给后续所有 PWA 方法)
await browser.installPWA({
manifestId,
installUrlOrBundleUrl: 'https://example.com/',
displayMode: 'standalone', // 可选:'standalone' | 'browser'
});
// 2. 查询 OS 集成状态
const state = await browser.getPWAState({manifestId});
console.log(state.badgeCount); // 应用图标上的徽章计数
console.log(state.fileHandlers); // 应用向 OS 注册的文件处理器
// 3. 启动应用,拿到其 Page
const page = await browser.launchPWA({manifestId});
console.log(await page.title());
await page.close();
// 4. 卸载后,查询将 reject
await browser.uninstallPWA({manifestId});
await expect(browser.getPWAState({manifestId})).rejects.toThrow();
测试 pwa.test.ts 中 "installs and uninstalls a PWA" 用例正是这条链路的自动化验证:安装后 getPWAState 能 resolve 出已安装应用的状态;uninstallPWA 之后再次调用 getPWAState 则 rejects.toThrow(),印证了"未知 manifest id 会 reject"的文档约定。
相关 API 文档
- Browser.installPWA():安装应用并获取 manifest id(
getPWAState的推荐前置步骤) - Browser.launchPWA():启动已安装应用并取得其页面
- Browser.uninstallPWA():卸载应用
- GetPWAStateOptions:参数接口
- PWAState:返回值接口
小结
Browser.getPWAState({manifestId}) 是 Puppeteer PWA 工具链中的"状态断言"入口:一次 PWA.getOsAppState CDP 调用即可拿到已安装应用的 badgeCount 与 fileHandlers。使用时记住三件事——启动时开启 pipe: true、manifest id 必须来自真实安装的应用(未安装即 reject)、浏览器配置网络限制时整组 PWA API 都会抛错。结合 installPWA 的返回值串联起安装—查询—启动—卸载的完整链路,就能对 PWA 的桌面集成行为做端到端的自动化验证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00