PAYATHON 2026

如何让 JavaScript fetch 使用与浏览器当前状态不同的 Cookie?

数据小陈

结论

普通网页 JavaScript 无法让浏览器原生 fetch() 在某一次请求中使用任意指定的 Cookie 集合。题目中的例子不能直接要求它只发送 key2=anothervalue2,同时排除浏览器已有的 key1=value1。

如果可以使用用户脚本,可以尝试 Tampermonkey 的特权请求 API。能否实现所需的组合,取决于脚本管理器和浏览器环境。

浏览器根据 Cookie 存储和匹配规则生成请求的 Cookie 请求头。Cookie 是禁止网页脚本设置的请求头,即使请求目标与当前页面同源,也不能通过 headers 指定。参见 Fetch Standard。

下面的写法无法达到目的:

// 无效方案:网页 fetch 不能自行设置 Cookie 请求头。
fetch('/page', {
  credentials: 'omit',
  headers: {
    Cookie: 'key2=anothervalue2'
  }
});

credentials 控制凭据的携带策略,不能逐个筛选或替换 Cookie:

  • omit:不携带浏览器 Cookie,也不接受响应中的 Set-Cookie。
  • same-origin:默认值,仅在同源请求中携带凭据。
  • include:允许跨源请求携带凭据,但仍受 Cookie 匹配规则和浏览器策略限制。

如果只需要完全不带 Cookie,可以使用下面的写法;它不能满足“仅发送自定义 Cookie”的需求。参见 Request.credentials 文档。

const response = await fetch('/page', {
  credentials: 'omit'
});
const html = await response.text();

用户脚本可以尝试什么方案

Tampermonkey 的 GM_xmlhttpRequest 提供 anonymous 和 cookie 参数。文档说明,anonymous 不发送 Cookie,cookie 则合并指定 Cookie 并替换同名 Cookie。因此,单独设置 cookie 不能保证排除已有的 key1。参见 Tampermonkey 请求 API 文档。

如果所用实现支持禁用已有 Cookie,同时注入显式指定的 Cookie,可以尝试以下组合。使用时请将示例域名和路径替换为实际目标:

// ==UserScript==
// @name         Fetch with custom cookies
// @match        https://example.com/*
// @grant        GM_xmlhttpRequest
// @connect      example.com
// ==/UserScript==

GM_xmlhttpRequest({
  method: 'GET',
  url: 'https://example.com/page',
  anonymous: true,
  cookie: 'key2=anothervalue2',
  onload(response) {
    console.log(response.status);
    console.log(response.responseText);
  },
  onerror(error) {
    console.error('Request failed', error);
  }
});

这段代码需要由 Tampermonkey 执行,普通网页控制台不提供该 API,也不能直接把它当作 Greasemonkey 或其他管理器的通用写法。

文档对这两个参数组合后的行为说明有限。使用时,应通过受控服务端日志或请求回显接口确认最终收到的 Cookie 是否只有 key2=anothervalue2,以及是否仍包含 key1。页面返回正常,并不能证明 Cookie 已按预期替换;也不要把真实登录 Cookie 发给公共回显服务。

为什么备份、删除、恢复不可靠

HttpOnly 限制网页 JavaScript 读取和修改 Cookie,但这些 Cookie 仍可随符合条件的 fetch() 请求发送。因此,document.cookie 无法完整备份、删除和恢复它们。参见 HttpOnly 属性说明。

即使只涉及普通 Cookie,这种办法也会改变共享的 Cookie 存储。其他标签页或并发请求可能在删除与恢复之间发出请求。同名 Cookie 也可能具有不同的 Domain、Path 和有效期,仅保存名称和值不足以完整恢复状态。

需要严格隔离时如何处理

如果用户脚本环境无法可靠实现该需求,可以将请求移到自己控制的后端,由后端 HTTP 客户端显式设置 Cookie: key2=anothervalue2,并避免附带其他会话的 Cookie。浏览器传给后端的 Cookie 不应自动透传给目标网站。

也可以使用独立浏览器配置文件或独立自动化上下文,建立单独的 Cookie 存储后再请求目标页面。这适合需要维持另一套会话的场景,但仍需自行设置所需 Cookie。

备注:内容仅供参考。