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

将Manifest V2中的webRequest迁移至declarativeNetRequest的问题求助

解决Manifest V3中webRequest到declarativeNetRequest的迁移问题

首先,你遇到的Cannot read properties of undefined (reading 'addListener')错误是因为declarativeNetRequest和webRequest的工作逻辑完全不同——它不是通过监听事件+回调处理的模式,而是通过定义并添加规则来实现网络请求修改,根本不存在declarativeNetRequest.onHeadersReceived.addListener这个API。

下面是针对你的需求(给指定域名添加CORS响应头)的完整迁移方案:

第一步:更新manifest.json权限配置

首先要在manifest中声明declarativeNetRequest权限,以及目标网站的主机权限(对应你原代码里的urls数组):

{
  "manifest_version": 3,
  "name": "你的扩展名称",
  "version": "1.0",
  "permissions": ["declarativeNetRequest"],
  "host_permissions": [
    "https://example.com/*",
    "*://*.example1.com/*"
  ],
  // 如果使用静态规则,需要添加这个字段
  "declarative_net_request": {
    "rule_resources": [
      {
        "id": "cors_rules",
        "enabled": true,
        "path": "rules.json"
      }
    ]
  }
}

方案一:使用静态规则(推荐,性能更优)

静态规则写在单独的JSON文件中(比如rules.json),扩展加载时自动生效,适合固定不变的规则:

[
  {
    "id": 1,
    "priority": 1,
    "action": {
      "type": "modifyHeaders",
      "responseHeaders": [
        {
          "header": "Access-Control-Allow-Origin",
          "operation": "set",
          "value": "*"
        },
        {
          "header": "Access-Control-Allow-Methods",
          "operation": "set",
          "value": "GET, PUT, POST, DELETE, HEAD, OPTIONS"
        }
      ]
    },
    "condition": {
      "urlFilter": "||example.com/*",
      "resourceTypes": ["xmlhttprequest", "script"]
    }
  },
  {
    "id": 2,
    "priority": 1,
    "action": {
      "type": "modifyHeaders",
      "responseHeaders": [
        {
          "header": "Access-Control-Allow-Origin",
          "operation": "set",
          "value": "*"
        },
        {
          "header": "Access-Control-Allow-Methods",
          "operation": "set",
          "value": "GET, PUT, POST, DELETE, HEAD, OPTIONS"
        }
      ]
    },
    "condition": {
      "urlFilter": "*://*.example1.com?test",
      "resourceTypes": ["xmlhttprequest", "script"]
    }
  }
]
  • operation: "set"会覆盖已有的同名响应头(避免重复头导致的浏览器报错),如果想保留原有头并追加新值,可以改用append。
  • resourceTypes指定要匹配的资源类型,可根据你的实际需求调整(比如只针对AJAX请求选择xmlhttprequest)。

方案二:使用动态规则(适合运行时需要调整规则的场景)

如果你需要在代码中动态添加/修改规则(类似原webRequest的动态逻辑),可以用chrome.declarativeNetRequest.updateDynamicRules实现:

// 动态添加CORS规则
async function addCorsRules() {
  try {
    await chrome.declarativeNetRequest.updateDynamicRules({
      addRules: [
        {
          id: 1,
          priority: 1,
          action: {
            type: "modifyHeaders",
            responseHeaders: [
              { header: "Access-Control-Allow-Origin", operation: "set", value: "*" },
              { header: "Access-Control-Allow-Methods", operation: "set", value: "GET, PUT, POST, DELETE, HEAD, OPTIONS" }
            ]
          },
          condition: {
            urlFilter: "||example.com/*",
            resourceTypes: ["xmlhttprequest", "script"]
          }
        },
        {
          id: 2,
          priority: 1,
          action: {
            type: "modifyHeaders",
            responseHeaders: [
              { header: "Access-Control-Allow-Origin", operation: "set", value: "*" },
              { header: "Access-Control-Allow-Methods", operation: "set", value: "GET, PUT, POST, DELETE, HEAD, OPTIONS" }
            ]
          },
          condition: {
            urlFilter: "*://*.example1.com?test",
            resourceTypes: ["xmlhttprequest", "script"]
          }
        }
      ],
      removeRuleIds: [] // 如果需要删除旧规则,在这里指定规则ID即可
    });
  } catch (err) {
    console.error("添加动态规则失败:", err);
  }
}

// 在扩展启动时执行规则添加
addCorsRules();

注意:动态规则有数量限制(默认最多500条),如果是固定不变的规则,优先选择静态规则方案。

核心差异说明

  • webRequest是事件驱动:拦截请求后在回调中手动修改;declarativeNetRequest是规则驱动:提前定义规则由浏览器直接应用,性能更优。
  • 不需要blocking这类标记,规则的执行优先级由priority字段控制。
  • 响应头的修改通过operation字段明确指定操作类型(set/append/remove),比手动push头信息更可控。

内容的提问来源于stack exchange,提问作者Gracie williams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:57:45