首页
/ Puppeteer 中 Browser.deleteMatchingCookies() 详解:按 name/domain/path/url/partitionKey 过滤器批量清除浏览器上下文 Cookie

Puppeteer 中 Browser.deleteMatchingCookies() 详解:按 name/domain/path/url/partitionKey 过滤器批量清除浏览器上下文 Cookie

2026-09-04 09:08:08作者:平淮齐Percy

导读

在自动化测试、爬虫与会话清理场景中,经常需要按条件批量删除 Cookie,而逐个调用 deleteCookie() 传入完整 Cookie 对象既繁琐又容易遗漏。本文基于 Puppeteer 官方 API 文档与源码,深入讲解 Browser.deleteMatchingCookies() 的定位、签名与 DeleteCookiesRequest 过滤器各字段(nameurldomainpathpartitionKey)的确切语义,并结合 BrowserContext.ts 的匹配实现与 browsercontext-cookies.test.ts 的真实测试用例,让你能写出可验证、可复现的批量清理代码。

方法定位与签名

Browser.deleteMatchingCookies()默认的 BrowserContext 中删除符合给定过滤条件的 Cookie。它本质上是 browser.defaultBrowserContext().deleteMatchingCookies() 的快捷方式(Shortcut),这一点在 Browser.deleteMatchingCookies() 文档 的 Remarks 部分有明确说明,源码也印证了这一委托关系(Browser.ts):

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

Signature

class Browser {
  deleteMatchingCookies(...filters: DeleteCookiesRequest[]): Promise<void>;
}

要点:

  • 变长参数(rest arguments):可以一次传入多个 DeleteCookiesRequest 过滤器,任一过滤器匹配上的 Cookie 都会被删除,过滤器之间是"或"关系;
  • 返回值Promise<void>,不返回被删除的 Cookie 列表;
  • 真正的筛选逻辑不在 Browser 上,而是在 BrowserContext.deleteMatchingCookies() 中实现(源码见 BrowserContext.ts)。如果你的脚本使用了隔离的 BrowserContext(如隐身上下文 browser.createBrowserContext()),调用 browser.deleteMatchingCookies() 不会清理隔离上下文中的 Cookie,应直接调用该上下文上的同名方法。

DeleteCookiesRequest 过滤器字段详解

过滤条件的数据结构是 DeleteCookiesRequest 接口,定义于 Cookie.ts

// packages/puppeteer-core/src/common/Cookie.ts
export interface DeleteCookiesRequest {
  /** Name of the cookies to remove.(必选:要删除的 Cookie 名称) */
  name: string;
  /** 指定后,仅删除该 URL 的域名与路径都匹配的 Cookie;否则只删当前页面域相关的 Cookie */
  url?: string;
  /** 指定后,仅删除 domain 完全相等的 Cookie */
  domain?: string;
  /** 指定后,仅删除 path 完全相等的 Cookie */
  path?: string;
  /** 指定后,仅删除处于给定分区键下的 Cookie(见下文 partitionKey 跨浏览器差异) */
  partitionKey?: CookiePartitionKey | string;
}

官方文档(puppeteer.deletecookiesrequest.md)给出的完整参数表如下:

属性 修饰符 类型 说明
domain optional string If specified, deletes only cookies with the exact domain.(只删除 domain 精确匹配的 Cookie)
name (必选) string Name of the cookies to remove.(要删除的 Cookie 名称)
partitionKey optional CookiePartitionKey | string 指定后只删除该分区键下的 Cookie。在 Chrome 中,partitionKey 匹配分区 Cookie 所处的顶级站点;在 Firefox 中,它匹配 WebDriver BiDi PartitionKey 中的 source origin
path optional string If specified, deletes only cookies with the exact path.(只删除 path 精确匹配的 Cookie)
url optional string 指定后,删除 name 相同且 domain 与 path 均与该 URL 匹配的所有 Cookie;否则只删除与当前页面域名相关的 Cookie

几个使用要点:

  • name 是唯一必选字段,所有匹配都先以 Cookie 名称相等为前提;
  • domain / path 都是精确匹配(源码中为 === 比较),不做子域或路径前缀推断。删除 example.com 的 Cookie 时,应传完整域名,而非前缀;
  • partitionKey 支持字符串或对象两种形式:字符串会被与 Cookie 分区键的 sourceOrigin 比较;对象形式则直接比较 sourceOrigin。此外 Chrome 与 Firefox 对分区键的解释不同(Chrome 对应分区 Cookie 可用的顶级站点,Firefox 对应 BiDi 的 source origin),跨浏览器脚本需要留意这一差异,测试用例中也有区分处理(见下文"实战示例")。

源码级实现:匹配与删除是如何发生的

BrowserContext.deleteMatchingCookies() 的完整实现在 BrowserContext.ts,其工作流程可以拆为两步:"筛选出目标 Cookie" + "调用 deleteCookie 逐一删除"。

第一步:在内存中筛选匹配的 Cookie

// packages/puppeteer-core/src/api/BrowserContext.ts
async deleteMatchingCookies(
  ...filters: DeleteCookiesRequest[]
): Promise<void> {
  const cookies = await this.cookies();
  const cookiesToDelete = cookies.filter(cookie => {
    return filters.some(filter => {
      if (filter.name === cookie.name) {
        if (filter.domain !== undefined && filter.domain === cookie.domain) {
          return true;
        }

        if (filter.path !== undefined && filter.path === cookie.path) {
          return true;
        }
        if (
          filter.partitionKey !== undefined &&
          cookie.partitionKey !== undefined
        ) {
          if (typeof cookie.partitionKey !== 'object') {
            throw new Error('Unexpected string partition key');
          }
          if (typeof filter.partitionKey === 'string') {
            if (filter.partitionKey === cookie.partitionKey?.sourceOrigin) {
              return true;
            }
          } else {
            if (
              filter.partitionKey.sourceOrigin ===
              cookie.partitionKey?.sourceOrigin
            ) {
              return true;
            }
          }
        }
        if (filter.url !== undefined) {
          const url = new URL(filter.url);
          if (
            url.hostname === cookie.domain &&
            url.pathname === cookie.path
          ) {
            return true;
          }
        }
        return true;
      }
      return false;
    });
  });
  await this.deleteCookie(...cookiesToDelete);
}

从源码结构看,有四个关键行为值得注意:

  1. 匹配的前提是 filter.name === cookie.name:名称不相等的 Cookie 永远不会被该过滤器命中,多个过滤器之间为 some() 的"或"语义。
  2. domainpathpartitionKeyurl 是四个并列的独立判断:只要其中一个条件(在"指定了该字段"的前提下)成立,Cookie 即被选中;url 的判断方式是用 new URL(filter.url) 解析后比较 hostname === cookie.domain && pathname === cookie.path
  3. partitionKey 匹配要求 Cookie 自身带有分区键:若 Cookie 的 partitionKeyundefined,该分支直接跳过,即分区键过滤器只能命中分区 Cookie(CHIPS 分区场景);同时若 Cookie 侧的分区键是字符串形态,会抛出 Unexpected string partition key 错误,可以推断该实现预期 Cookie 侧始终返回对象形态的分区键。
  4. 末尾的 return true 意味着"仅指定 name 的过滤器会删除该名称下的所有 Cookie"(在默认上下文中即所有域下同名 Cookie)。文档中 url 字段"否则只删当前页面域相关的 Cookie"的表述,在源码层面实际体现为:不带 url 时不做域限定。编写脚本时建议显式带上 domain/path/url 之一,让删除范围更可控。

第二步:deleteCookie 的底层删除机制

筛选出的 Cookie 最终交给 deleteCookie() 完成删除,其实现相当简洁——把每个 Cookie 的 expires 改写为 1(一个已过期的时间戳),再走 setCookie 写入:

// packages/puppeteer-core/src/api/BrowserContext.ts
async deleteCookie(...cookies: Cookie[]): Promise<void> {
  return await this.setCookie(
    ...cookies.map(cookie => {
      return {
        ...cookie,
        expires: 1,
      };
    }),
  );
}

也就是说,Puppeteer 的 Cookie 删除并不是向浏览器发送"删除"命令,而是重新设置一个已过期版本的 Cookie,由浏览器自行清理过期项。这也解释了为什么 deleteMatchingCookies 返回 void 而不会报告删除数量——删除结果需要通过 context.cookies() 再次查询来验证。

实战示例与测试用例佐证

仓库测试套件 browsercontext-cookies.test.ts 中的 BrowserContext.deleteMatchingCookies describe 块,覆盖了 5 种过滤器形态的端到端验证,是最直接的参考用法。测试先写入 cookie1cookie2 两条同名域 Cookie,然后按不同过滤器删除,断言只剩 cookie2

// test/src/browsercontext-cookies.test.ts(节选)
const filters: DeleteCookiesRequest[] = [
  { name: 'cookie1' },
  { url: 'https://example.test/test', name: 'cookie1' },
  { domain: 'example.test', name: 'cookie1' },
  { path: '/test', name: 'cookie1' },
  { name: 'cookie1', partitionKey: { sourceOrigin: 'https://example.test' } },
];
for (const filter of filters) {
  it(`should delete cookies matching ${JSON.stringify(filter)}`, async () => {
    // ...
    await context.deleteMatchingCookies(filter);
    const cookies = await context.cookies();
    expect(cookies).toHaveLength(1);
    expect(cookies[0]!.name).toBe('cookie2');
  });
}

其中分区 Cookie 的写入方式体现了 Chrome/Firefox 的差异处理(测试节选自 browsercontext-cookies.test.ts):

const topLevelSite = 'https://example.test';
await context.setCookie({
  name: 'cookie1',
  value: 'secret',
  domain: new URL(topLevelSite).hostname,
  path: '/test',
  expires: -1,
  httpOnly: false,
  secure: true,
  partitionKey: isChrome
    ? { sourceOrigin: topLevelSite, hasCrossSiteAncestor: false }
    : undefined,
  // ...
});

一个可运行的清理脚本

结合 Browser 侧快捷方式,一个典型的会话清理脚本如下(适用于 launch() 启动的浏览器,默认操作 defaultBrowserContext):

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

// 删除当前上下文里 example.com 上名为 session_token 的 Cookie
await browser.deleteMatchingCookies({
  name: 'session_token',
  domain: 'example.com',
});

// 同时按多个过滤器清理:另一个名字 + 特定路径下的 Cookie
await browser.deleteMatchingCookies(
  { name: 'csrf_token', domain: 'example.com' },
  { name: 'cart_items', path: '/cart' },
);

// 验证:重新拉取 Cookie 列表确认目标项已消失
const remaining = await browser.cookies();
console.log(remaining.map(c => c.name));

await browser.close();

注意事项(均有源码/测试依据):

  • 变长参数传入的多个过滤器是"或"关系,命中任一即删;
  • domainpath 为精确匹配,url 会被解析为 hostnamepathname 两段做相等比较;
  • 操作对象是默认上下文;若你在 browser.createBrowserContext() 返回的上下文中建立了会话,请在该上下文上调用 deleteMatchingCookies()BrowserContext.deleteMatchingCookies 文档);
  • 删除后建议像测试用例那样调用 context.cookies() 复查,确认目标 Cookie 已不存在。

与相关 API 的关系

Puppeteer 在 Cookie 清理上提供三层入口,选择依据是"你手里有什么":

API 适用场景 实现要点
browser.deleteCookie(...cookies: Cookie[]) 已持有完整的 Cookie 对象(例如刚从 browser.cookies() 里取出) 直接委托默认上下文,将 expires 改写为 1 后 setCookieBrowserContext.ts
browser.deleteMatchingCookies(...filters) 只知道名称,可能附带 domain/path/url/partitionKey 条件,想批量清理 cookies() 全量拉取,内存过滤后逐一走 deleteCookie
page.deleteCookie()(页面级) 仅关心当前页面域相关的 Cookie Page.ts 源码注释中明确推荐在需要跨页面/跨域清理时改用 Browser.deleteMatchingCookies / BrowserContext.deleteMatchingCookies

小结

Browser.deleteMatchingCookies() 是 Puppeteer 中按条件批量清理 Cookie 的快捷入口:它以 name 为必选锚点,叠加 domain/path/url 的精确匹配与 partitionKey 的分区匹配,在默认 BrowserContext 内完成"拉取—过滤—过期改写"三步删除。理解 BrowserContext.ts 中的并列匹配逻辑与 测试用例 的 5 种过滤器形态,就能在测试会话隔离、爬虫登录态清理等场景下精准地控制删除范围,避免误删或漏删。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.79 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
988
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384