ARTICLE DETAIL

资讯详情

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

Puppeteer BrowserContext.deleteCookie() 深度解析:在浏览器上下文中精确删除 Cookie

Puppeteer BrowserContext.deleteCookie() 深度解析:在浏览器上下文中精确删除 Cookie Puppeteer BrowserContext.deleteCookie() 深度解析在浏览器上下文中精确删除 Cookie【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer本篇指南聚焦 Puppeteer 的BrowserContext.deleteCookie()方法——它用于从指定浏览器上下文BrowserContext中移除 Cookie是实现登录态清理、多账号隔离、会话重置等自动化场景的关键 API。读完本文你将掌握该方法的完整签名与参数要求为什么必须传入“完整 Cookie 对象”、其底层“改写过期时间”的实现原理以及它与Browser.deleteCookie()、deleteMatchingCookies()、BiDi/CDP 两套协议实现之间的调用关系并结合官方测试用例给出可直接运行的删 Cookie 实操代码。方法签名与参数说明官方 API 文档 puppeteer.browsercontext.deletecookie.md 给出的签名如下class BrowserContext { deleteCookie(...cookies: Cookie[]): Promisevoid; }参数类型说明cookiesCookie[]要删除的完整Cookie 对象可传多个可变参数返回值为Promisevoid调用后所有匹配的 Cookie 会被同步移除。这里的Cookie类型是比“写入用”的CookieData更完整的结构。从源码 Cookie.ts 可以看到两者定义CookieData写入参数name、value、domain必填path、secure、httpOnly、sameSite、expires、priority、sourceScheme、partitionKey可选Cookie读取结果继承自CookieData在CookieData基础上强制要求path、expires、size、secure、session字段齐备另有 Chrome 专属的partitionKeyOpaque。这正是官方文档强调传入“Complete cookie object”的原因deleteCookie的参数类型是Cookie而非CookieData即你应当把context.cookies()或browser.cookies()读取回来的完整 Cookie 对象直接回传而不是手工拼一个只有name/domain的简略对象。Cookie的关键属性含义引自 puppeteer.cookie.md 与 Cookie.ts属性类型含义expiresnumber过期时间自 UNIX epoch 的秒数会话 Cookie 为-1pathstringCookie 路径secureboolean是否为 Secure Cookiesessionboolean是否为会话 CookiesizenumberCookie 大小partitionKeyOpaqueboolean可选partition key 是否为 opaque仅 Chrome 支持而用于“按条件删除”的DeleteCookiesRequest接口同样定义在 Cookie.ts则允许只给name 可选的url/domain/path/partitionKey过滤条件它服务于下一节介绍的deleteMatchingCookies()。实现原理deleteCookie 并非“真删除”而是改写过期时间这是理解该方法行为的关键。deleteCookie在抽象基类 BrowserContext.ts 中是一个具体实现非抽象方法其全部逻辑为// packages/puppeteer-core/src/api/BrowserContext.ts async deleteCookie(...cookies: Cookie[]): Promisevoid { return await this.setCookie( ...cookies.map(cookie { return { ...cookie, expires: 1, }; }), ); }可以看到它把每一个待删除的 Cookie 的expires改写为1即 1970-01-01 00:00:01 UTC一个已经过去的时刻然后委托给setCookie。浏览器接收到“把该 Cookie 更新为已过期”的指令后即将其清除——这与网页端通过document.cookie name; expires...清除 Cookie 是同一思路只是发生在浏览器存储层。这一设计带来两个值得注意的推论删除动作复用写入通道。无论底层是 Chrome DevTools ProtocolCDP还是 WebDriver BiDiPuppeteer 都不需要单独的“删除”指令即可在两种协议上保持一致语义因为删除最终都走setCookie的实现路径。传参必须完整。由于内部是用对象展开...cookie后调用setCookie如果传入的 Cookie 缺少name/value/domain等定位字段底层就无法确定要“置过期”的是哪一条记录删除会失效。两套协议下的底层调用链BrowserContext.deleteCookie位于协议无关的api/层真正的setCookie由各协议的具体BrowserContext实现完成因此删除的底层链路随协议不同而异CDPChrome DevTools Protocol实现在 cdp/BrowserContext.ts 中setCookie通过连接发送Storage.setCookies命令并带上browserContextId以锁定当前上下文override 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), }; }), }); }对应的读取方法cookies()则发送Storage.getCookies。也就是说CDP 模式下deleteCookie的最终效果是向浏览器发送一条Storage.setCookies其中携带expires: 1的 Cookie 副本。WebDriver BiDi 实现在 bidi/BrowserContext.ts 中setCookie将 Puppeteer 的 Cookie 字段逐一转换为 BiDi 的Storage.PartialCookiedomain、name、value、path、httpOnly、secure、sameSite、expiry等再调用userContext.setCookie完成写入其中expiry由convertCookiesExpiryCdpToBiDi(cookie.expires)转换而来——因此expires: 1这个“已过期时间戳”同样会原样生效达到删除效果。从源码结构看这种“过期时间即删除”的约定是 Puppeteer 刻意保持跨协议一致的行为读者在调试网络日志时会看到deleteCookie触发的是 set/update 类命令而非 remove 类命令。在 Cookie 体系中的位置与 Browser 和 Page 级 API 的关系Puppeteer 的 Cookie API 分三层BrowserContext.deleteCookie处在“浏览器上下文”这一中间层Browser 层默认上下文快捷方式Browser.ts 中的deleteCookie仅是转发/** * Removes cookies from the default BrowserContext. * * Shortcut for browser.defaultBrowserContext().deleteCookie(). */ async deleteCookie(...cookies: Cookie[]): Promisevoid { return await this.defaultBrowserContext().deleteCookie(...cookies); }因此browser.deleteCookie(...)与browser.defaultBrowserContext().deleteCookie(...)等价要操作用户上下文如 incognito 上下文的 Cookie必须走BrowserContext.deleteCookie。Page 层已废弃Page.ts 中的page.deleteCookie被明确标注为deprecated官方建议改用Browser.deleteCookie、BrowserContext.deleteCookie或两个deleteMatchingCookies。新代码不应再依赖页面级 Cookie API。同层补充deleteMatchingCookies当你手上没有“完整 Cookie 对象”、只记得名字和域名时BrowserContext.ts 提供了按DeleteCookiesRequest过滤的批量删除async deleteMatchingCookies(...filters: DeleteCookiesRequest[]): Promisevoid { const cookies await this.cookies(); const cookiesToDelete cookies.filter(cookie { return filters.some(filter { if (filter.name cookie.name) { // 依次检查 domain / path / partitionKey / url 是否匹配 // ...详见源码 L321-L358 return true; } return false; }); }); await this.deleteCookie(...cookiesToDelete); }其匹配规则是“name必须相等再按domain、path、partitionKey、url任一条件进一步确认”。实现上它先cookies()拉全量过滤后再复用deleteCookie——这再次印证了删除的本质是“定位 置过期”。实战示例可复制运行的删除流程以下示例整合了官方指南 cookies.md 的写法与仓库测试 browsercontext-cookies.test.ts 中BrowserContext.deleteCookies用例的真实参数结构import puppeteer from puppeteer; const browser await puppeteer.launch(); const context await browser.createBrowserContext(); const page await context.newPage(); // 1. 先写入两个 Cookieexpires: -1 表示会话 Cookie await context.setCookie( { name: cookie1, value: 1, domain: localhost, path: /, expires: -1, httpOnly: false, secure: false, sourceScheme: NonSecure, }, { name: cookie2, value: 2, domain: localhost, path: /, expires: -1, httpOnly: false, secure: false, sourceScheme: NonSecure, }, ); // 2. 删除时传入从存储中读出的完整 Cookie 对象推荐做法 const [cookie1] (await context.cookies()).filter(c c.name cookie1); await context.deleteCookie(cookie1); // 验证cookie2 仍然存在 console.log(await context.cookies()); await context.close();官方指南 cookies.md 给出的默认上下文版本同理browser.deleteCookie({...}, {...})直接接收完整 Cookie 对象一次可变参数删除多条。指南最后也明确说明Browser上这些操作默认上下文的方法同样存在于BrowserContext类上。测试用例中的完整参数对照仓库测试 browsercontext-cookies.test.ts 展示了删除时传入的完整对象形态可与上面对照await context.deleteCookie({ name: cookie1, value: 1, domain: localhost, path: /, expires: -1, size: 16, // Cookie 读回时携带的 size 字段 httpOnly: false, secure: false, session: true, // 会话 Cookie 标记 sourceScheme: NonSecure, });注意value、size、session这些字段在“定位”一条 Cookie 时看似无关紧要但它们正是Cookie类型要求的完整结构的一部分测试还断言了删除后document.cookie只剩cookie22验证了精确删除行为。另一个页面级用例 cookies.test.ts 则演示了“cookies()读回后整体传给deleteCookie”的惯用法const cookies await page.cookies(); await page.deleteCookie(...cookies); // 清空当前全部 Cookie expect(await page.cookies()).toHaveLength(0);该用例针对已废弃的page.deleteCookie新代码请换成context.deleteCookie。使用建议与注意事项优先读回再删除。deleteCookie需要完整Cookie对象最稳妥的流程是const cookies await context.cookies()→ 按name/domain筛选 → 回传筛选结果。只知名字和域名时用deleteMatchingCookies。它接受DeleteCookiesRequestname必填url/domain/path/partitionKey可选省去读回全量对象的手工筛选。上下文隔离是前提。BrowserContext的文档注释BrowserContext.ts说明每个上下文拥有独立的存储cookies/localStorage 等在 Chrome 中所有非默认上下文均为 incognito。删除操作只影响所属上下文不会跨上下文清理。分区 Cookie 的 partitionKey。对于带partitionKeyCHIPS 分区的 Cookie删除时保留原对象中的partitionKey字段底层会通过convertCookiesPartitionKeyFromPuppeteerToCdp等函数正确转换后写入见 cdp/BrowserContext.ts。partitionKey在 Chrome 中对应{sourceOrigin, hasCrossSiteAncestor}FirefoxBiDi下仅支持sourceOrigin——这一点在测试 browsercontext-cookies.test.ts 的“should find partitioned cookie”用例中有明确体现。不要混用写入参数与删除参数。setCookie接受可精简的CookieData如 cookies.md 中的写法而deleteCookie要求完整Cookie两者的expires语义也不同——写入时-1表示会话 Cookie删除时该字段会被内部强制覆写为1传什么都无所谓但字段本身必须存在。小结BrowserContext.deleteCookie()的公开接口极简——传入一个或多个完整 Cookie 对象、返回Promisevoid但其内部实现BrowserContext.ts揭示了“删除 将expires改写为1后走setCookie通道”的跨协议统一设计CDP 侧最终落到Storage.setCookies、BiDi 侧落到userContext.setCookie。掌握这一点后再配合deleteMatchingCookies()的条件过滤能力与Browser层的默认上下文快捷方式即可覆盖 Puppeteer 中 Cookie 清理的全部常见场景。【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表