替换屏蔽型 Web 请求监听器

在 Manifest V3 中修改网络请求

Manifest V3 更改了扩展程序处理网络请求修改的方式。扩展程序会指定规则来描述在满足一组给定条件时要执行的操作,而不是拦截网络请求并在运行时使用 chrome.webRequest 更改请求。请使用 Declarative Net Request API 执行此操作。

Web Request API 和声明式网络请求 API 有很大的区别。您需要根据用例重新编写代码,而不是将一个函数调用替换为另一个函数调用。本部分将引导您完成此过程。

在 Manifest V2 中,屏蔽网络请求可能会显著降低扩展程序的性能以及所支持网页的性能。webRequest 命名空间支持 9 个潜在阻塞事件,每个事件处理的事件处理脚本数量不受限制。更糟糕的是,每个网页都可能被多个扩展程序屏蔽,而且这样做所需的权限具有侵犯性。Manifest V3 可通过将回调替换为声明性规则来防范此问题。

这里共分为三部分,介绍对不属于扩展 Service Worker 的代码进行哪些更改,本文是其中的第二部分。其中介绍了如何将 Manifest V2 使用的屏蔽性 Web 请求转换成 Manifest V3 所使用的声明性网络请求。另外两部分介绍更新迁移到 Manifest V3 所需的代码以及提高安全性

更新权限

manifest.json 中的 "permissions" 字段进行以下更改。

  • 如果您不再需要观察网络请求,请移除 "webRequest" 权限。
  • 将匹配模式从 "permissions" 移至 "host_permissions"

您需要根据您的使用场景添加其他权限。这些权限通过其支持的用例进行描述。

创建声明性网络请求规则

如需创建声明性 net 请求规则,需要向 manifest.json 添加 "declarative_net_request" 对象。"declarative_net_request" 代码块包含指向规则文件的 "rule_resource" 对象数组。规则文件包含一组对象,用于指定操作以及调用这些操作的条件。

常见使用场景

以下各部分介绍了声明性 net 请求的常见用例。以下说明仅提供简要说明。如需详细了解此处的所有信息,请参阅 chrome.declarativeNetRequest 下的 API 参考文档

屏蔽单个网址

Manifest V2 中的一个常见用例是在后台脚本中使用 onBeforeRequest 事件来屏蔽网络请求。

Manifest V2 后台脚本
chrome.webRequest.onBeforeRequest.addListener((e) => {
    return { cancel: true };
}, { urls: ["https://www.example.com/*"] }, ["blocking"]);

对于 Manifest V3,请使用 "block" 操作类型创建新的 declarativeNetRequest 规则。请注意示例规则中的 "condition" 对象。其 "urlFilter" 取代了传递给 webRequest 监听器的 urls 选项。"resourceTypes" 数组指定要屏蔽的资源的类别。此示例将仅屏蔽主 HTML 网页,但您却可以(例如)只屏蔽字体。

Manifest V3 规则文件
[
  {
    "id" : 1,
    "priority": 1,
    "action" : { "type" : "block" },
    "condition" : {
      "urlFilter" : "||example.com",
      "resourceTypes" : ["main_frame"]
    }
  }
]

为此,您需要更新该扩展程序的权限。在 manifest.json 中,将 "webRequestBlocking" 权限替换为 "declarativeNetRequest" 权限。请注意,由于屏蔽内容不需要主机权限,因此该网址已从 "permissions" 字段中移除。如上所示,规则文件会指定声明性网络请求应用到的一个或多个主机。

如果您想尝试此操作,我们的示例代码库中提供了以下代码。

Manifest V2
  "permissions": [
    "webRequestBlocking",
    "https://*.example.com/*"
  ]
Manifest V3
  "permissions": [
    "declarativeNetRequest",
  ]

重定向多个网址

Manifest V2 中的另一个常见用例是使用 BeforeRequest 事件重定向网络请求。

Manifest V2 后台脚本
chrome.webRequest.onBeforeRequest.addListener((e) => {
    console.log(e);
    return { redirectUrl: "https://developer.chrome.com/docs/extensions/mv3/intro/" };
  }, { 
    urls: [
      "https://developer.chrome.com/docs/extensions/mv2/"
    ]
  }, 
  ["blocking"]
);

对于 Manifest V3,请使用 "redirect" 操作类型。与之前一样,"urlFilter" 会替换传递给 webRequest 监听器的 url 选项。请注意,在此示例中,规则文件的 "action" 对象包含一个 "redirect" 字段,其中包含要返回的网址,而不是要过滤的网址。

Manifest V3 规则文件
[
  {
    "id" : 1,
    "priority": 1,
    "action": {
      "type": "redirect",
      "redirect": { "url": "https://developer.chrome.com/docs/extensions/mv3/intro/" }
    },
    "condition": {
      "urlFilter": "https://developer.chrome.com/docs/extensions/mv2/",
      "resourceTypes": ["main_frame"]
    }
  }

在这种情况下,还需要更改扩展程序的权限。与之前一样,将 "webRequestBlocking" 权限替换为 "declarativeNetRequest" 权限。系统再次将这些网址从 manifest.json 移到了规则文件中。请注意,除了主机权限之外,重定向还需要 "declarativeNetRequestWithHostAccess" 权限。

如果您想尝试此操作,我们的示例代码库中提供了以下代码。

Manifest V2
  "permissions": [
    "webRequestBlocking",
    "https://developer.chrome.com/docs/extensions/*",
    "https://developer.chrome.com/docs/extensions/reference"
  ]
Manifest V3
  "permissions": [
    "declarativeNetRequestWithHostAccess"
  ],
  "host_permissions": [
    "https://developer.chrome.com/*"
  ]

阻止 Cookie

在 Manifest V2 中,要屏蔽 Cookie,需要先拦截网络请求标头,然后再发送这些标头并移除特定的 Cookie。

Manifest V2 后台脚本
chrome.webRequest.onBeforeSendHeaders.addListener(
  function(details) {
    removeHeader(details.requestHeaders, 'cookie');
    return {requestHeaders: details.requestHeaders};
  },
  // filters
  {urls: ['https://*/*', 'http://*/*']},
  // extraInfoSpec
  ['blocking', 'requestHeaders', 'extraHeaders']);

Manifest V3 也通过规则文件中的规则实现这一点。这次的操作类型为 "modifyHeaders"。该文件接受 "requestHeaders" 对象数组,用于指定要修改的标头以及如何修改这些标头。请注意,"condition" 对象仅包含 "resourceTypes" 数组。它支持的值与前面的示例相同。

如果您想尝试此操作,我们的示例代码库中提供了以下代码。

清单 V3 manifest.json
[
  {
    "id": 1,
    "priority": 1,
    "action": {
      "type": "modifyHeaders",
      "requestHeaders": [
        { "header": "cookie", "operation": "remove" }
      ]
    },
    "condition": {
      "urlFilter": "|*?no-cookies=1",
      "resourceTypes": ["main_frame"]
    }
  }
]

在这种情况下,还需要更改扩展程序的权限。与之前一样,将 "webRequestBlocking" 权限替换为 "declarativeNetRequest" 权限。

Manifest V2
  "permissions": [
    "webRequest",
    "webRequestBlocking",
    "https://*/*",
    "http://*/*"
  ],
Manifest V3
  "permissions": [
    "declarativeNetRequest",
  ],
  "host_permissions": [
    ""
  ]