首页
/ Puppeteer BrowserContext.setCookie 详解:在浏览器上下文中直接写入 Cookie 的完整指南

Puppeteer BrowserContext.setCookie 详解:在浏览器上下文中直接写入 Cookie 的完整指南

2026-09-04 21:41:48作者:幸俭卉

本文围绕 Puppeteer 的 BrowserContext.setCookie() 方法展开,讲清它的函数签名、CookieData 参数对象的每一个字段、底层 CDP 与 WebDriver BiDi 两套实现路径,以及在自动化测试和登录态保持等场景中可直接复制的用法。读完后,你可以独立完成"在任意浏览器上下文中预设 Cookie、验证 Cookie 写入、再将其删除"的完整闭环,并理解不同字段在 Chrome 与 Firefox 下的行为差异。

方法定位:它属于 BrowserContext 的存储隔离层

BrowserContext 代表浏览器中独立的"用户上下文",每个上下文拥有完全隔离的存储(cookies、localStorage 等)。Puppeteer 启动浏览器时至少存在一个默认上下文,也可以通过 Browser.createBrowserContext() 创建新的上下文(在 Chrome 中,所有非默认上下文都是 incognito)。Cookie 操作就是定义在这一抽象层上的:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

// 创建一个独立的(incognito)上下文
const context = await browser.createBrowserContext();
// 在上下文中直接预设 Cookie,无需先打开任何页面
await context.setCookie({
  name: 'auth_token',
  value: 'my-token-value',
  domain: 'example.com',
  path: '/',
});

const page = await context.newPage();
await page.goto('https://example.com/profile'); // 已携带 Cookie

await context.close();

抽象声明位于 api/BrowserContext.ts

// packages/puppeteer-core/src/api/BrowserContext.ts
abstract class BrowserContext {
  /**
   * Gets all cookies in the browser context.
   */
  abstract cookies(): Promise<Cookie[]>;

  /**
   * Sets a cookie in the browser context.
   */
  abstract setCookie(...cookies: CookieData[]): Promise<void>;
}

对应文档见 BrowserContext.setCookieBrowserContextCookies 指南

函数签名与参数

官方签名(来自 API 文档):

class BrowserContext {
  abstract setCookie(...cookies: CookieData[]): Promise<void>;
}
参数 类型 说明
cookies CookieData[] 一个或多个要写入的 Cookie 参数对象,支持变长参数一次性批量写入
返回值 Promise<void> 写入完成时 resolve;不返回已写入的 Cookie,需用 cookies() 回读验证

CookieData 是"浏览器级"Cookie 写入 API 的参数类型,与页面级的 CookieParamPage.setCookie 使用)的关键区别在于:CookieDatadomain 是必填项,而页面级 API 允许通过 url 推导域名。这一点决定了 BrowserContext.setCookie 可以在没有任何页面打开的情况下预设 Cookie——这正是测试场景中最常用的模式。

CookieData 字段逐项说明

以下字段完整继承自 CookieData 接口文档,并与源码 common/Cookie.ts 中的定义一一对应:

字段 必填 类型 说明
name string Cookie 名称
value string Cookie 值
domain string Cookie 所属域名
path string Cookie 路径,未指定时由浏览器按默认规则处理(通常为 /
secure boolean 是否为 Secure Cookie(仅通过 HTTPS 发送)
httpOnly boolean 是否为 HttpOnly Cookie(JS 不可读写)
sameSite CookieSameSite'Strict' | 'Lax' | 'None' | 'Default' SameSite 属性;'Default' 表示交给浏览器采用默认策略
expires number 过期时间(UNIX 时间戳,秒);不设置则为会话 Cookie,会话 Cookie 的约定表示为 -1
priority CookiePriority'Low' | 'Medium' | 'High' Cookie 优先级,仅 Chrome 支持
sourceScheme CookieSourceScheme'Unset' | 'NonSecure' | 'Secure' 原始设置方所在的 source scheme,仅 Chrome 支持
partitionKey CookiePartitionKey | string Cookie 分区键:在 Chrome 中对应分区 Cookie 可用的顶级站点(topLevelSite),在 Firefox 中对应 BiDi PartitionKey 的 source origin

几个容易被忽略的语义细节:

  • expires: -1 是"会话 Cookie"的显式写法。cookies() 回读时,会话 Cookie 会以 expires: -1, session: true 的形式出现,测试 browsercontext-cookies.test.ts 中就断言了这一点。
  • sameSite: 'Default' 是一个特殊值。在 CDP 路径上,convertSameSiteFromPuppeteerToCdp 只会把 Strict/Lax/None 原样传给 Chrome,Default 会被映射为 undefined(即"不设 SameSite"),由浏览器自行决定默认策略——测试中因此断言回读结果可能是 'Default''Lax'undefined,取决于浏览器。
  • partitionKey 的双形态:Chrome 下是对象 {sourceOrigin, hasCrossSiteAncestor?}hasCrossSiteAncestor 也仅 Chrome 支持),Firefox 下通常传 sourceOrigin 字符串即可;测试用例展示了两种形态的对照写法。

底层实现:CDP 与 BiDi 两条路径

从源码结构看,BrowserContext.setCookie 是抽象方法,两套协议后端各自实现,这是理解其行为边界的关键。

CDP 路径(Chrome 默认)

CdpBrowserContext.setCookie 直接把整批 Cookie 转换为 CDP 参数后发出一次 Storage.setCookies 调用:

// packages/puppeteer-core/src/cdp/BrowserContext.ts
override async setCookie(...cookies: CookieData[]): Promise<void> {
  return await this.#connection.send('Storage.setCookies', {
    browserContextId: this.#id,
    cookies: cookies.map(cookie => {
      return {
        ...cookie,
        partitionKey: convertCookiesPartitionKeyFromPuppeteerToCdp(
          cookie.partitionKey,
        ),
        sameSite: convertSameSiteFromPuppeteerToCdp(cookie.sameSite),
      };
    }),
  });
}

注意其中 browserContextId 被显式传入——这意味着写入是上下文级操作,Cookie 只会落在该上下文的隔离存储中,不会污染其他 incognito 上下文或默认上下文。

WebDriver BiDi 路径(Firefox / BiDi 模式)

BidiBrowserContext.setCookie 采用逐条写入:每条 CookieData 被转换为 BiDi 的 Storage.PartialCookie,最终通过 UserContext.setCookie 发送 storage.setCookie 命令,并在 partition 参数中携带 userContext 标识,保证写入落在正确的用户上下文。值得注意的转换细节:

  • expires 通过 convertCookiesExpiryCdpToBiDi 转换为 BiDi 的 expiry-1 即无过期时间,仍表示会话 Cookie);
  • sameSiteconvertCookiesSameSiteCdpToBiDi 映射为 BiDi 枚举;
  • 注释标明 sourceSchemepriorityurl 属于 "Chrome-specific properties",通过 cdpSpecificCookiePropertiesFromPuppeteerToBidi 处理——这与 CookieData 文档中"Supported only in Chrome"的标注一致,在 Firefox 下设置这些字段不产生语义。

与 Browser.setCookie 的关系:默认上下文快捷方式

Browser.setCookie 只是默认上下文的转发:

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

cookies.md 指南中的示例就是在 Browser 上调用,等价于对 browser.defaultBrowserContext() 调用 setCookie

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

// 为 localhost 域名一次性写入两条 Cookie
await browser.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',
  },
);

console.log(await browser.cookies()); // 打印可用 cookies

选择建议:若只想给默认上下文注入登录态等 Cookie,用 browser.setCookie 最简洁;若需要多账号隔离、并行会话或验证"上下文间 Cookie 不串扰",则应通过 createBrowserContext() 拿到独立上下文并在其上调用 setCookie

配套方法:deleteCookie 的巧妙实现

BrowserContextdeleteCookie 并没有单独的底层命令,而是复用 setCookie 完成——把待删 Cookie 展开后强制设置 expires: 1(一个已过去的时间戳),让浏览器自行清除:

async deleteCookie(...cookies: Cookie[]): Promise<void> {
  return await this.setCookie(
    ...cookies.map(cookie => {
      return {
        ...cookie,
        expires: 1,
      };
    }),
  );
}

这意味着:

  1. 删除操作与写入走完全相同的 CDP/BiDi 通道,行为一致性有保障;
  2. 删除的前提是提供完整的 Cookie 对象(由 cookies() 回读得到),匹配依据是 name + domain + path 等字段;
  3. 更灵活的批量删除由 deleteMatchingCookies 提供,它先 cookies() 回读全量,再按 DeleteCookiesRequest 过滤条件(namedomainpathurlpartitionKey)筛选后调用 deleteCookie,实现逻辑见 api/BrowserContext.ts

写入后验证:测试中的标准闭环

官方测试 browsercontext-cookies.test.ts 展示了"写入 → 访问 → 页面内可见"的完整验证流程,这正是实际使用中推荐的做法:

// 写入会话 Cookie
await context.setCookie({
  name: 'infoCookie',
  value: 'secret',
  domain: 'localhost',
  path: '/',
  expires: -1,
  httpOnly: false,
  secure: false,
  sourceScheme: 'NonSecure',
});

await page.goto(server.EMPTY_PAGE);

// 页面内 JS 直接可见(非 HttpOnly)
expect(
  await page.evaluate(() => document.cookie),
).toEqual('infoCookie=secret');

验证时注意两点:

  • httpOnly Cookie 可在页面内通过 document.cookie 读到;httpOnly: true 的 Cookie 只会随请求发送,页面 JS 读不到,此时只能用 context.cookies() 验证。
  • secure: true 的 Cookie 需要通过 HTTPS 页面(或测试环境开启 acceptInsecureCerts: true)才能被正常携带和回读。

典型应用场景

结合 Cookies 指南的定位——"在操作浏览器存储层面提前 get/set/delete cookies,方便在测试中存取和恢复特定 Cookie"——BrowserContext.setCookie 最典型的落地场景是:

  1. 登录态保持:从生产环境或上一次会话导出 Cookie(cookies() 返回的完整对象数组本身就是可序列化的 JSON),在新会话启动后通过 setCookie(...savedCookies) 一次性注入,跳过登录页与验证码;
  2. 多租户/多账号隔离测试:每个 createBrowserContext() 是一个独立存储域,向不同上下文分别 setCookie 注入不同账号的身份,互不干扰,测试结束 context.close() 即自动清空该账号的全部存储;
  3. 模拟服务端 Set-Cookie:对无法直接控制的第三方站点,可预先按目标域写入 Cookie(如 A/B 实验标记、地区标记),再观察页面行为差异。

小结

BrowserContext.setCookie(...cookies: CookieData[]) 是 Puppeteer 在浏览器上下文存储层写入 Cookie 的入口:必填 name/value/domain,可选字段覆盖 path、过期、SameSite、Secure、HttpOnly 及 Chrome 专属的 priority/sourceScheme/partitionKey;CDP 实现一次发送 Storage.setCookies,BiDi 实现逐条发送 storage.setCookieBrowser.setCookie 只是默认上下文的快捷方式,deleteCookie 则是借由"过期时间置为过去"复用的同一通道。掌握字段语义(尤其是 expires: -1sameSite: 'Default' 与分区键的双形态)与写入后的验证方法,即可在测试与自动化脚本中可靠地管理任意上下文的 Cookie 状态。

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

项目优选

收起
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.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 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
987
504
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384