ARTICLE DETAIL

资讯详情

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

Puppeteer 中 CookieSameSite 类型详解:Strict / Lax / None / Default 在 Chrome 与 Firefox 中的取值、转换与验证

Puppeteer 中 CookieSameSite 类型详解:Strict / Lax / None / Default 在 Chrome 与 Firefox 中的取值、转换与验证 Puppeteer 中 CookieSameSite 类型详解Strict / Lax / None / Default 在 Chrome 与 Firefox 中的取值、转换与验证【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteerPuppeteer 的 API 文档定义了CookieSameSite类型它是操作浏览器 Cookie 时描述 SameSite 状态的核心枚举对应 IETF 草案draft-west-first-party-cookies所规范的跨站 Cookie 策略。本篇以该类型定义为骨架结合 puppeteer-core 源码 与测试用例讲清四个取值的确切含义、它在setCookie/CookieData/CookieParam等 API 中的位置以及 Puppeteer 如何在 CDP 协议与 WebDriver BiDi 协议之间做双向转换帮助你正确地为自动化测试写入和断言 SameSite Cookie。一、CookieSameSite 类型的定义官方 API 文档 CookieSameSite 类型 给出的完整定义如下Represents the cookies SameSite status: https://tools.ietf.org/html/draft-west-first-party-cookiesexport type CookieSameSite Strict | Lax | None | Default;该定义位于源码文件 Cookie.ts带有public标记属于 Puppeteer 对外公开 API 的一部分。它是一个字符串字面量联合类型只有四个合法取值。这四个值分别对应浏览器 SameSite 属性在不同策略下的状态取值语义Strict严格模式仅在完全同站same-site请求中携带该 Cookie任何跨站导航都不发送且跨站提交的表单也不携带。Lax宽松模式同站请求正常携带跨站 GET 顶级导航可携带但跨站 POST 或子资源请求不携带。这是当前主流浏览器的实际默认行为。None关闭 SameSite 限制跨站请求也会携带 Cookie。现代浏览器要求None必须与Secure属性同时出现否则拒绝设置。Default未显式指定 SameSite 属性时的“默认”状态。浏览器会根据自身策略落到某个实际行为通常是Lax因此读回时可能呈现为不同值。值得注意的是Default并不是标准Set-Cookie头中出现的值而是 Puppeteer 用来表示“调用方没有显式指定 SameSite”这一状态的哨兵值——这一点对理解后面的协议转换逻辑非常关键。二、CookieSameSite 在 Cookie 相关 API 中的位置CookieSameSite并不是孤立的它在 common/Cookie.ts 中与一组相邻类型共同构成 Puppeteer 的 Cookie 数据模型CookieData浏览器级 Cookie APIBrowser/BrowserContext/Page的setCookie使用的参数对象其中可选字段sameSite?: CookieSameSite源码定义注释为 “Cookie SameSite type.”。CookieParam页面级 Cookie API 使用的参数对象同样带有sameSite?: CookieSameSite源码定义并额外支持url字段来推断默认 domain / path / source scheme。Cookie读取 Cookie 时返回的完整对象继承自CookieData因此同样携带sameSite字段可能为undefined。与CookieSameSite并列导出的还有两个相关类型便于对照理解整个 Cookie 模型源码export type CookiePriority Low | Medium | High; export type CookieSourceScheme Unset | NonSecure | Secure;官方 Cookies 使用指南 展示了setCookie/cookies/deleteCookie的基本用法例如直接向浏览器存储写入两个localhost域的会话 Cookie。在此基础上若要控制跨站行为只需在参数对象中追加sameSite字段即可例如import puppeteer from puppeteer; const browser await puppeteer.launch(); const page await browser.newPage(); await page.goto(https://example.com); // 显式指定 SameSite 策略 await page.setCookie({ name: session, value: abc123, sameSite: Strict, httpOnly: true, }); // 读取并断言 SameSite 值 const [cookie] await page.cookies(); console.log(cookie?.sameSite); // Strict三、源码级解析Puppeteer 值如何转换为 CDP 协议值Puppeteer 的CookieSameSite与 Chrome DevTools ProtocolCDP的Network.CookieSameSite并不完全对齐——CDP 只有Strict/Lax/None三种没有Default。转换逻辑在 cdp/Page.ts 中/** * internal */ export function convertSameSiteFromPuppeteerToCdp( sameSite: CookieSameSite | undefined, ): Protocol.Network.CookieSameSite | undefined { switch (sameSite) { case Strict: case Lax: case None: return sameSite; default: return undefined; } }从源码结构看转换规则是三个具体值原样透传Default以及未指定被归一为undefined即“不向 CDP 传递 sameSite 字段”把默认策略的决定权完全交给 Chrome 自身。该转换在CdpPage.setCookie中被调用源码完整调用链为override async setCookie(...cookies: CookieParam[]): Promisevoid { const pageURL this.url(); const startsWithHTTP pageURL.startsWith(http); const items cookies.map(cookie { const item Object.assign({}, cookie); if (!item.url startsWithHTTP) { item.url pageURL; // 未提供 url 时用当前页面 URL 推断 domain/path } // 断言about:blank 与 data: 页面不能携带 cookie return item; }); await this.deleteCookie(...items); // 先删除同名旧 cookie if (items.length) { await this.#primaryTargetClient.send(Network.setCookies, { cookies: items.map(cookieParam { return { ...cookieParam, partitionKey: convertCookiesPartitionKeyFromPuppeteerToCdp( cookieParam.partitionKey, ), sameSite: convertSameSiteFromPuppeteerToCdp(cookieParam.sameSite), }; }), }); } }这里有几个值得注意的实现细节setCookie会先调用deleteCookie清除同名旧 Cookie再发送Network.setCookies保证写入是幂等的。未提供url且当前页面是http(s)页面时自动用页面 URL 填充从而让浏览器推断 domain / path / source scheme。sameSite: Default到达这里会被转换函数丢弃最终 Chrome 按其自身默认策略处理该 Cookie。四、WebDriver BiDi 协议下的双向转换在 WebDriver BiDi 协议模式下Puppeteer 需要在自己的CookieSameSite与 BiDi 的Network.SameSite小写枚举且包含default之间做双向转换。实现位于 bidi/Page.tsfunction convertCookiesSameSiteBiDiToCdp( sameSite: Bidi.Network.SameSite | undefined, ): CookieSameSite { switch (sameSite) { case strict: return Strict; case lax: return Lax; case none: return None; default: return Default; } } export function convertCookiesSameSiteCdpToBiDi( sameSite: CookieSameSite | undefined, ): Bidi.Network.SameSite { switch (sameSite) { case Strict: return Bidi.Network.SameSite.Strict; case Lax: return Bidi.Network.SameSite.Lax; case None: return Bidi.Network.SameSite.None; default: return Bidi.Network.SameSite.Default; } }与 CDP 路径的关键差异在于BiDi 协议本身有default枚举值因此Default不会被丢弃而是显式映射为Bidi.Network.SameSite.Default。这意味着在 BiDi 模式下写入sameSite: Default的 Cookie浏览器会以协议层的 default 语义处理。这也解释了为什么“未指定 SameSite 时读回什么值”在不同浏览器 / 协议组合下会出现差异——详见下一节的测试断言。五、测试用例对四种取值的验证仓库中的 cookies.test.ts 为每个 SameSite 取值都提供了端到端验证是理解实际行为最可靠的依据1.Strict与Lax的写入与读回源码由测试服务器在响应头中下发Set-Cookie: ab; SameSiteStrict或Lax页面加载后断言const cookies await page.cookies(); expect(cookies).toHaveLength(1); expect(cookies[0]!.sameSite).toBe(Strict); // 或 Lax2.Default的读回存在浏览器差异源码通过page.setCookie({ name: a, value: b, sameSite: Default })写入后断言是宽容的// Different browsers have different sameSite values for the Default sameSite. expect([Default, Lax, undefined]).toContain(cookies[0]!.sameSite);这一行注释直接印证了前文的推断Default只是 Puppeteer 层的语义标记真实存储行为由浏览器决定读回结果可能是Default、Lax或undefined。因此编写断言时对Default取值应保持宽松匹配而不要做精确相等断言。3. 未指定 SameSite 时的行为源码服务器下发不带 SameSite 属性的ab测试针对 Firefox WebDriver BiDi 组合显式断言sameSite为Default其余浏览器组合不做强断言——再次说明跨浏览器默认值的差异。4.None必须配合 HTTPS源码测试在 HTTPS 跨域 iframe 场景写入sameSite: None的 Cookie随后断言读回的 Cookie 同时满足sameSite: None、secure: true、sourceScheme: Secure。这与浏览器安全策略一致SameSiteNone的 Cookie 被自动标记为secure无法在纯 HTTP 环境下生效。六、使用建议与边界说明综合定义、转换代码与测试断言使用CookieSameSite时建议遵循以下原则跨站场景必须显式使用None并确保 Cookie 落在 HTTPS 站点且带secure否则浏览器会静默丢弃该 Cookie测试用例中secure: true与sourceScheme: Secure的断言即为佐证。Default只用于“不指定”语义。写入时它会退化为浏览器默认策略当前多为 Lax 行为读取时可能表现为Default/Lax/undefined三种形态之一跨浏览器断言应使用toContain式的宽松匹配。协议模式影响Default的传递性。CDP 模式下Default被转换为undefined不传给 Chrome见 convertSameSiteFromPuppeteerToCdpWebDriver BiDi 模式下则会映射到协议的default枚举见 convertCookiesSameSiteCdpToBiDi。在双协议间迁移测试脚本时这是最容易产生行为差异的点。该类型与CookiePriority、CookieSourceScheme配合使用三者共同构成 common/Cookie.ts 中 Cookie 模型的策略维度其中priority与sourceScheme按源码注释“Supported only in Chrome”Firefox 下可能不生效。本文所有结论均可在仓库中复核类型定义见 docs/api/puppeteer.cookiesamesite_2.md 与 packages/puppeteer-core/src/common/Cookie.ts协议转换见 packages/puppeteer-core/src/cdp/Page.ts 与 packages/puppeteer-core/src/bidi/Page.ts行为验证见 test/src/cookies.test.ts基础用法见 docs/guides/cookies.md。【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表