Puppeteer Browser.cookies() 详解:获取默认浏览器上下文完整 Cookie 列表的机制与实战
2026/9/8 21:24:27 网站建设 项目流程

Puppeteer Browser.cookies() 详解:获取默认浏览器上下文完整 Cookie 列表的机制与实战

【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer

Browser.cookies()是 Puppeteer 中在浏览器级别读取 Cookie 的核心 API:它以一次调用返回默认BrowserContext中所有页面的全部 Cookie,是登录态检查、请求调试、状态序列化等场景的常用入口。本文以Browser.cookies()文档为骨架,结合当前仓库的源码实现与测试用例,讲清它的签名、返回结构、底层 CDP 调用链以及它与BrowserContext.cookies()的等价关系,读完后可直接在生产脚本中正确使用并排查 Cookie 读取问题。

方法概述与签名

Browser.cookies()方法用于返回默认 BrowserContext 中的所有 Cookie(Returns all cookies in the default BrowserContext)。原始 API 文档位于 docs/api/puppeteer.browser.cookies.md,其定义如下:

Signature

class Browser { cookies(): Promise<Cookie[]>; }

Returns:Promise<Cookie[]>—— 返回一个 Promise,解析结果为 Cookie 对象数组。

Remarks(文档原注)

官方文档对它的定位是一句话:"Shortcut forbrowser.defaultBrowserContext().cookies()",即它只是默认浏览器上下文cookies()方法的快捷方式。这意味着:

  • 它只能读取默认上下文的 Cookie;通过browser.createBrowserContext()创建的其它(隔离/无痕)上下文中的 Cookie,需要直接调用对应上下文实例的BrowserContext.cookies()(见 docs/api/puppeteer.browsercontext.cookies.md);
  • 默认上下文不能被关闭(源码中对close()assert(this.#id, 'Default BrowserContext cannot be closed!')的断言,见下文实现分析),因此browser.cookies()永远有稳定的读取入口。

这一"快捷方式"的定位在源码中得到逐字印证:

// packages/puppeteer-core/src/api/Browser.ts async cookies(): Promise<Cookie[]> { return await this.defaultBrowserContext().cookies(); }

参见 api/Browser.ts#L689-L692。调用链完全等价于defaultBrowserContext()BrowserContext.cookies(),没有任何额外的过滤或状态缓存逻辑。

返回值:Cookie 接口的完整字段

browser.cookies()返回的每个元素都是 Cookie 接口对象,其定义为interface Cookie extends CookieData(见 common/Cookie.ts#L59-L85)。CookieData提供namevaluedomainpathhttpOnlysecuresameSitepartitionKey等写入与读取通用的基础字段;Cookie在此基础上补充了五个由浏览器回传、只读性质的字段,完整字段表如下(继承自 docs/api/puppeteer.cookie.md):

属性修饰符类型说明
pathstringCookie path.(Cookie 路径)
expiresnumberCookie 过期时间,UNIX 纪元起的秒数;会话 Cookie 为-1
secureboolean是否为 Secure Cookie(仅 HTTPS 传输)
sessionboolean是否为会话 Cookie
sizenumberCookie 大小
partitionKeyOpaqueoptionalbooleanCookie 分区键是否不透明。仅 Chrome 支持

几个字段在自动化实践中值得特别注意:

  • expiressession的对应关系expires === -1的 Cookie 即会话 Cookie,sessiontrue。这也是 Puppeteer 删除 Cookie 的原理——BrowserContext.deleteCookie()内部就是把目标 Cookie 的expires改写为1(一个过去的时间点)再写回,从而让浏览器立即将其过期(见 api/BrowserContext.ts#L299-L308)。因此browser.cookies()读到的过期时间可以直接用于判断"该 Cookie 是否随会话消失"。
  • partitionKeyOpaque仅 Chrome 支持:它对应 Chrome 第三方 Cookie 分区(CHIPS)机制中的不透明分区键。同文件中的 CookiePartitionKey 定义了sourceOrigin与可选的hasCrossSiteAncestor两个字段,用于描述 Cookie 分区归属。
  • sameSite/priority/sourceScheme等枚举类型CookieSameSite'Strict' | 'Lax' | 'None' | 'Default')、CookiePriority'Low' | 'Medium' | 'High')、CookieSourceScheme'Unset' | 'NonSecure' | 'Secure')均在 common/Cookie.ts#L13-L30 中定义,可用于断言服务端下发的 Cookie 策略是否符合预期。

底层实现:CDP 调用链与数据转换

Browser.cookies()本身只是一层转发,真正干活的是其所在实现的BrowserContext子类。CDP(Chrome DevTools Protocol)实现中,cookies()直接下发Storage.getCookies命令,并把返回的partitionKey从 CDP 结构转换为 Puppeteer 结构:

// packages/puppeteer-core/src/cdp/BrowserContext.ts override async cookies(): Promise<Cookie[]> { const {cookies} = await this.#connection.send('Storage.getCookies', { browserContextId: this.#id, }); return cookies.map(cookie => { return { ...cookie, partitionKey: cookie.partitionKey ? { sourceOrigin: cookie.partitionKey.topLevelSite, hasCrossSiteAncestor: cookie.partitionKey.hasCrossSiteAncestor, } : undefined, }; }); }

参见 cdp/BrowserContext.ts#L146-L161。从这段源码可以得到三个实现事实:

  1. 作用域由browserContextId决定:默认上下文的#idundefined,即Storage.getCookies不带该参数时查询的就是浏览器默认作用域的全部 Cookie——这正是browser.cookies()能"一次拿全"的原因。
  2. partitionKey.topLevelSite被重命名为sourceOrigin:如果你对比过原始 CDP 返回结构与 Puppeteer 结果,会发现字段名不一致,这是映射层刻意对齐跨浏览器语义的结果(BiDi 规范中对应PartitionKey的 source origin)。
  3. 同一接口在 BiDi 后端也有独立实现packages/puppeteer-core/src/bidi/BrowserContext.ts同样实现了cookies(),因此该方法在 Chrome(CDP)与 Firefox(WebDriver BiDi)上均可用;但由于partitionKey/partitionKeyOpaque等字段标注"Supported only in Chrome",跨浏览器时以文档字段说明为准。

典型使用示例

结合源码中deleteMatchingCookies()的依赖方式(它先调用cookies()拉全量、再按name/domain/path/url/partitionKey过滤删除,见 api/BrowserContext.ts#L315-L364),browser.cookies()最常见的用法是"读取—断言—清理"三步:

import puppeteer from 'puppeteer'; const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); // 1. 读取默认上下文的完整 Cookie 列表 const cookies = await browser.cookies(); console.log(cookies.map(c => `${c.name}=${c.value} (expires: ${c.expires})`)); // 2. 断言某个分区/属性特征(Chrome 特有字段,Firefox 可能为 undefined) const partitioned = cookies.find(c => c.partitionKeyOpaque); // 3. 精确清理某个域下的全部 Cookie // 注意:deleteMatchingCookies 属于 BrowserContext 方法 await browser.defaultBrowserContext().deleteMatchingCookies({ domain: 'example.com', }); await browser.close();

适用前提与限制:

  • browser.cookies()只覆盖默认上下文。若脚本使用了browser.createBrowserContext()创建的隔离上下文(Chrome 中即 incognito 上下文,各上下文 Cookie/localStorage 相互隔离,见 api/BrowserContext.ts#L61-L107 的类注释),必须对该上下文实例调用context.cookies()
  • 该方法读取的是浏览器存储层的全量 Cookie,与当前页面 URL 无关;如果只需要某页面作用域的 Cookie,可对比使用页面级的page.cookies(),再结合domain/path字段自行过滤。
  • partitionKeypartitionKeyOpaqueprioritysourceScheme等字段文档明确标注 Chrome-only,跨浏览器代码中建议做可选字段判断。

测试用例中的行为验证

仓库的集成测试对该 API 的行为提供了可验证依据:

  • test/src/cookies.test.ts 覆盖了 Cookie 设置与读取的核心行为(会话 Cookie、过期时间、domain/path 匹配等);
  • test/src/browsercontext-cookies.test.ts 验证了不同BrowserContext之间 Cookie 相互隔离、以及上下文级cookies()的读写;
  • test/src/defaultbrowsercontext.test.ts 中涉及默认上下文的 Cookie 场景,与browser.cookies()走默认上下文路径的语义一致。

这些测试文件可以在test/目录配合 Mocha 运行器(见 tools/mocha-runner)执行,用于回归验证 Cookie API 在版本升级后的行为是否稳定。

小结

Browser.cookies()的定位非常收敛:它等价于browser.defaultBrowserContext().cookies(),最终在 CDP 后端翻译为一次Storage.getCookies调用,返回默认作用域内全部Cookie[]。理解这一点后,实践中三个要点即可覆盖绝大多数场景:返回对象按Cookie接口解析(expires: -1即会话 Cookie,Chrome 独有partitionKeyOpaque);只读默认上下文,隔离上下文需走BrowserContext.cookies();删除 Cookie 依赖"改写expires后写回"的机制,因此deleteMatchingCookies()这类操作本质上依赖cookies()提供的全量快照作为过滤输入。

【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询