You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过函数调用动态使用declarativeNetRequest的modifyHeaders功能?

如何通过函数调用动态使用declarativeNetRequest的modifyHeaders功能?

嘿,我来帮你解决这个问题!你现在遇到的核心问题是对declarativeNetRequest的工作机制理解有点偏差——它的规则是纯静态的配置结构,根本没法直接在里面写函数或者异步调用,这就是你报错的原因。浏览器会把这些规则编译成高效的内部执行逻辑,只接受字符串、数字这类可序列化的静态值,自定义函数和await调用在规则里完全不被支持。

下面给你两种针对性的解决方案,根据你的实际需求选就行:

方案一:提前计算静态值(适合值不需要每次请求都更新的场景)

如果你的header值不需要每次请求都重新计算,只是初始化的时候动态生成一次,那可以先在规则外部完成异步计算,再把结果塞进规则里:

const MY_CUSTOM_RULE_ID = 1;

async function updateDynamicHeaderRule() {
  // 第一步:先在规则外完成所有异步计算
  const rawValue = "my custom header value";
  const encoder = new TextEncoder();
  const data = encoder.encode(rawValue);
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  const hashBase64 = btoa(String.fromCharCode(...hashArray));

  // 第二步:用计算好的静态值更新规则
  await chrome.declarativeNetRequest.updateDynamicRules({
    removeRuleIds: [MY_CUSTOM_RULE_ID],
    addRules: [
      {
        id: MY_CUSTOM_RULE_ID,
        priority: 1,
        action: {
          type: "modifyHeaders",
          requestHeaders: [
            {
              operation: "set",
              header: "my custom name",
              value: hashBase64 // 直接用提前算好的静态值
            }
          ]
        },
        condition: {
          resourceTypes: ["main_frame", "sub_frame"]
        }
      }
    ]
  });
}

// 调用函数初始化规则
updateDynamicHeaderRule().catch(err => console.error("更新规则失败:", err));

方案二:实时动态计算(适合每次请求都要生成新值的场景)

如果你的header值需要每次请求都重新计算,那declarativeNetRequest的静态规则就满足不了了,得换成chrome.webRequestAPI——它允许在请求触发的瞬间动态修改headers,完全支持异步操作。

首先要在manifest.json里添加必要的权限:

{
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["webRequest", "webRequestBlocking"],
  "host_permissions": ["<all_urls>"] // 或者指定你需要拦截的具体域名
}

然后在background.js里编写逻辑:

chrome.webRequest.onBeforeSendHeaders.addListener(
  async (details) => {
    // 每次请求触发时,实时计算header值
    const rawValue = "my custom header value";
    const encoder = new TextEncoder();
    const data = encoder.encode(rawValue);
    const hashBuffer = await crypto.subtle.digest("SHA-256", data);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    const hashBase64 = btoa(String.fromCharCode(...hashArray));

    // 修改请求头:先找有没有同名header,有就替换,没有就新增
    const requestHeaders = details.requestHeaders || [];
    const targetHeaderIndex = requestHeaders.findIndex(h => h.name.toLowerCase() === "my custom name");
    
    if (targetHeaderIndex !== -1) {
      requestHeaders[targetHeaderIndex].value = hashBase64;
    } else {
      requestHeaders.push({ name: "my custom name", value: hashBase64 });
    }

    return { requestHeaders };
  },
  { urls: ["<all_urls>"], types: ["main_frame", "sub_frame"] }, // 匹配你需要的请求类型和域名
  ["blocking", "requestHeaders", "extraHeaders"] // 必须声明blocking权限才能修改请求头
);

再给你理清楚为什么原来的写法报错

你之前把getValue函数和await getValue()直接写在规则的requestHeaders数组里,这完全不符合declarativeNetRequest的规则要求——浏览器解析规则时会把它当成静态JSON结构,根本不认识里面的函数和await关键字,自然会抛出语法错误。这类声明式API的设计初衷就是用静态配置实现高效拦截,不支持嵌入自定义执行逻辑。

备注:内容来源于stack exchange,提问作者Stan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 18:49:27