ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Puppeteer Browser.setCookie() 完全指南:浏览器级 Cookie 注入与 CDP/BiDi 底层实现解析

Puppeteer Browser.setCookie() 完全指南:浏览器级 Cookie 注入与 CDP/BiDi 底层实现解析 Puppeteer Browser.setCookie() 完全指南浏览器级 Cookie 注入与 CDP/BiDi 底层实现解析【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer本文基于 Puppeteer 官方 API 文档Browser.setCookie()展开系统讲解该方法的签名、参数对象CookieData的每个字段、返回值与典型用法并结合仓库源码还原它从 API 调用到 CDPStorage.setCookies和 WebDriver BiDistorage.setCookie协议的完整实现链路。读完后你可以熟练地在浏览器层面预置 Cookie如登录态注入并理解sameSite、partitionKey等字段在两种协议下的转换细节与限制。方法定位与签名Browser.setCookie()是 Puppeteer 提供的浏览器级Cookie 写入接口作用于浏览器的默认BrowserContext。官方文档对它的定义非常明确Sets cookies in the default BrowserContext.也就是说它与页面级page.setCookie()、上下文级browserContext.setCookie()相比区别在于作用域它写入的是默认浏览器上下文中的 Cookie 集合适合在打开任何页面之前就完成会话凭据、测试用 Cookie 的预置。方法签名见 官方 API 文档class Browser { setCookie(...cookies: CookieData[]): Promisevoid; }参数cookiesCookieData对象的可变参数列表一次调用可以同时设置多个 Cookie返回值Promisevoid没有数据返回完成后即代表 Cookie 已提交给浏览器备注Remarks它是browser.defaultBrowserContext().setCookie()的快捷方式。从源码结构看这一快捷方式的描述与实现完全一致。在 Browser.ts 中/** * Sets cookies in the default {link BrowserContext}. * * remarks * * Shortcut for * {link BrowserContext.setCookie | browser.defaultBrowserContext().setCookie()}. */ async setCookie(...cookies: CookieData[]): Promisevoid { return await this.defaultBrowserContext().setCookie(...cookies); }实现只有一行转发取出默认上下文再把所有CookieData参数原样透传给其setCookie()。同一文件中的cookies()和deleteCookie()也是同样的快捷方式模式三者构成默认上下文上的 Cookie 读写删完整闭环。基本用法示例import puppeteer from puppeteer; const browser await puppeteer.launch(); // 浏览器级写入默认浏览器上下文 await browser.setCookie({ name: session_id, value: abc123, domain: example.com, // 注意domain 在 CookieData 中是必填字段 path: /, httpOnly: true, secure: true, sameSite: Lax, // 过期时间UNIX 时间戳秒省略则为会话 Cookie expires: Math.floor(Date.now() / 1000) 60 * 60, }); // 可以一次写入多个 Cookie await browser.setCookie( {name: theme, value: dark, domain: example.com}, {name: lang, value: zh, domain: example.com, path: /app}, ); // 用配套的 cookies() 快捷方法验证写入结果 const cookies await browser.cookies(); console.log(cookies.map(c ${c.name}${c.value})); await browser.close();典型应用场景包括在page.goto()之前注入登录令牌以绕过登录流程、为测试环境预置功能开关feature flagCookie、跨页面共享同一份凭据而不依赖某个具体页面的 URL。CookieData 参数对象逐字段说明setCookie的入参类型是 CookieData其完整定义位于 Cookie.ts。它与页面级 API 使用的CookieParam同文件 L93-L146相比有一个关键差异差异点CookieData浏览器级CookieParam页面级domain必填string可选url存在时可由浏览器推导默认 domainurl不存在该字段可选用于关联 request-URI 并影响默认 domain/path这是因为浏览器级 API 没有页面上下文可供推导所以必须显式给出domain——这也是调用Browser.setCookie()时最容易踩的坑漏掉domain会直接触发 TypeScript 类型错误。各字段含义与取值如下字段类型必填说明namestring是Cookie 名称valuestring是Cookie 值domainstring是Cookie 域名pathstring否Cookie 路径secureboolean否是否仅限安全HTTPS传输httpOnlyboolean否是否禁止页面脚本读取sameSiteCookieSameSite否取值Strict \| Lax \| None \| Defaultexpiresnumber否过期时间UNIX 时间戳秒不设置则为会话 CookiepriorityCookiePriority否取值Low \| Medium \| High仅 Chrome 支持sourceSchemeCookieSourceScheme否取值Unset \| NonSecure \| Secure仅 Chrome 支持partitionKeyCookiePartitionKey \| string否分区 CookieCHIPS的分区键这些类型别名的定义同样集中在 Cookie.tsexport type CookieSameSite Strict | Lax | None | Default; export type CookiePriority Low | Medium | High; export type CookieSourceScheme Unset | NonSecure | Secure; export interface CookiePartitionKey { sourceOrigin: string; hasCrossSiteAncestor?: boolean; // 仅 Chrome 支持 }几个使用上的要点会话 Cookie不传expires即得到会话 Cookie浏览器关闭即失效。返回侧的Cookie接口Cookie.ts L59-L85会额外给出session: boolean和expires会话 Cookie 为-1用于回读确认。partitionKey双形态可以传字符串表示顶级站点或对象{sourceOrigin, hasCrossSiteAncestor?}。在 Chrome 中它对应 CDP 的topLevelSite分区键在 Firefox 中对应 WebDriver BiDi 的 source origin。Chrome 专属字段priority和sourceScheme在文档中被明确标注 Supported only in Chrome跨浏览器使用时应做能力判断。读回的Cookie类型还包含sizeCookie 大小与partitionKeyOpaque分区键是否不透明仅 Chrome便于在断言时核对注入结果。底层实现一CDP 协议路径Chrome / Chromium在 CDP 实现中BrowserContext.setCookie()位于 cdp/BrowserContext.tsoverride async setCookie(...cookies: CookieData[]): Promisevoid { return await this.#connection.send(Storage.setCookies, { browserContextId: this.#id, cookies: cookies.map(cookie { return { ...cookie, partitionKey: convertCookiesPartitionKeyFromPuppeteerToCdp( cookie.partitionKey, ), sameSite: convertSameSiteFromPuppeteerToCdp(cookie.sameSite), }; }), }); }调用链为browser.setCookie()→defaultBrowserContext().setCookie()→ CDP 命令Storage.setCookies命令参数中携带browserContextId以限定作用域到具体浏览器上下文。这里值得注意两个字段在发送前的净化转换1.sameSite的降级处理转换函数convertSameSiteFromPuppeteerToCdp定义在 cdp/Page.tsswitch (sameSite) { case Strict: case Lax: case None: return sameSite; default: return undefined; // Default 被映射为 undefined即不发送 }也就是说Default在 CDP 路径上会被显式丢弃交由浏览器自行决定默认 SameSite 策略。2.partitionKey的形态归一convertCookiesPartitionKeyFromPuppeteerToCdpcdp/Page.ts把 Puppeteer 的双形态分区键统一转换成 CDP 协议对象if (typeof partitionKey string) { return {topLevelSite: partitionKey, hasCrossSiteAncestor: false}; } return { topLevelSite: partitionKey.sourceOrigin, hasCrossSiteAncestor: partitionKey.hasCrossSiteAncestor ?? false, };字符串形式等价于hasCrossSiteAncestor: false对象形式缺省时同样默认false。这与 Cookie.ts 中在 Chrome 中映射到 CDP 的topLevelSite分区键的注释一致。同一文件中回读方向也有对应处理cookies()方法cdp/BrowserContext.ts L146-L161调用Storage.getCookies并把 CDP 返回的partitionKey反向展开为 Puppeteer 的{sourceOrigin, hasCrossSiteAncestor}结构保证写入/读出两侧的类型对称。底层实现二WebDriver BiDi 协议路径Firefox / BiDi 模式当以 BiDi 协议驱动浏览器时走的是另一条链路。BidiBrowserContext.setCookie()位于 bidi/BrowserContext.tsoverride async setCookie(...cookies: CookieData[]): Promisevoid { await Promise.all( cookies.map(async cookie { const bidiCookie: Bidi.Storage.PartialCookie { domain: cookie.domain, name: cookie.name, value: {type: string, value: cookie.value}, ...(cookie.path ! undefined ? {path: cookie.path} : {}), ...(cookie.httpOnly ! undefined ? {httpOnly: cookie.httpOnly} : {}), ...(cookie.secure ! undefined ? {secure: cookie.secure} : {}), ...(cookie.sameSite ! undefined ? {sameSite: convertCookiesSameSiteCdpToBiDi(cookie.sameSite)} : {}), ...{expiry: convertCookiesExpiryCdpToBiDi(cookie.expires)}, // Chrome-specific properties. ...cdpSpecificCookiePropertiesFromPuppeteerToBidi( cookie, sourceScheme, priority, url, ), }; return await this.userContext.setCookie( bidiCookie, convertCookiesPartitionKeyFromPuppeteerToBiDi(cookie.partitionKey), ); }), ); }与 CDP 路径对比有三个结构性差异逐条并发发送BiDi 侧对每个 Cookie 单独构造Bidi.Storage.PartialCookie并调用userContext.setCookie()用Promise.all并发等待而不是 CDP 那样一次性批量提交字段按需展开所有可选字段都使用未定义则不发送的展开语法避免把undefined当作有效值传给协议Chrome 专属字段的透传sourceScheme、priority等通过cdpSpecificCookiePropertiesFromPuppeteerToBidi处理注释标明它们是 Chrome-specific properties——即 BiDi 通道下这些字段能否生效同样取决于底层浏览器能力。UserContext.setCookie()的终点在 bidi/core/UserContext.ts发送的是 BiDi 命令storage.setCookie。因此整个 BiDi 链路为browser.setCookie()→ 默认上下文 →storage.setCookie按 user context 作用域写入。与页面级、上下文级 setCookie 的分工Puppeteer 中存在三个层级的 Cookie 写入入口从源码抽象层可以看到它们的职责划分api/BrowserContext.tsabstract setCookie(...cookies: CookieData[]): Promisevoid真正的抽象契约浏览器级方法就是它的一个转发api/Page.tsabstract setCookie(...cookies: CookieParam[]): Promisevoid页面级版本使用CookieParam允许通过url字段让浏览器推导 domain/path具体协议实现分别由cdp/Page.tsNetwork.setCookies按页面主 target 发送与上文 CDP/BiDi 上下文实现承接。实践选型建议需要全局/跨页面生效的凭据如站点登录态、全局配置开关用browser.setCookie()需要针对特定页面 URL 自动推导作用域时用page.setCookie()需要隔离环境多账号、独立存储时先用browser.createBrowserContext()再对具体上下文调用setCookie()。测试用例中的验证方式仓库测试套件对该能力有直接覆盖可作为断言写法的参考test/src/browsercontext-cookies.test.ts在指定BrowserContext上context.setCookie({...})写入后通过context.cookies()回读并按name/value/domain等字段做断言如 L49、L84 等多处写入用例test/src/cookies.test.ts覆盖页面级写入、httpOnly/secure/sameSite等属性回显、以及两个页面共享浏览器上下文内 Cookie 的可见性等场景test/src/defaultbrowsercontext.test.ts专门验证默认浏览器上下文的行为——这正是Browser.setCookie()的目标作用域包括默认上下文的不可关闭性等约束。这些用例印证了文档的核心语义浏览器级写入作用于默认上下文回读接口cookies()会返回符合 Cookie 接口 的完整对象含path、expires、size、session等回填字段。关键限制与注意事项domain必填CookieData与CookieParam最重要的结构差异。TypeScript 项目中漏写会直接编译报错JS 项目中则可能导致 Cookie 写入范围不符合预期。会话 Cookie省略expires即为会话 Cookie仅在当前浏览器会话内有效回读时expires表现为-1、session为true。sameSite: Default在 CDP 下被静默丢弃从 convertSameSiteFromPuppeteerToCdp 的源码结构看只有Strict/Lax/None会实际下发需要精确控制时不要依赖Default。priority与sourceScheme仅 Chrome 支持在 Firefox 或 BiDi 通道下这两个字段的实际效果取决于底层浏览器能力BiDi 实现中它们被归入 Chrome-specific properties 处理。partitionKey字符串简写传字符串时等价于{sourceOrigin: 该字符串, hasCrossSiteAncestor: false}需要表达跨站祖先关系时必须使用对象形态。作用域是默认上下文如果脚本此前通过browser.createBrowserContext()创建了隔离上下文browser.setCookie()不会写入那个隔离上下文需显式调用对应上下文的setCookie()。小结Browser.setCookie()是 Puppeteer 中面向自动化登录态注入、测试数据预置的高频 API签名简单可变参数 Promisevoid但参数对象CookieData覆盖了现代 Cookie 的全部维度——安全属性secure/httpOnly/sameSite、生命周期expires、作用域domain/path、以及 Chrome 专属的priority/sourceScheme与分区 CookiepartitionKey。其底层在 CDP 侧收敛为单条Storage.setCookies批量命令在 BiDi 侧展开为按条并发的storage.setCookie两条路径都在发送前对sameSite与partitionKey做了协议化转换理解这些转换细节是跨浏览器编写可靠 Cookie 注入逻辑的关键。【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表