替换屏蔽型 Web 请求监听器

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

Web 请求 API 和声明式 Net 请求 API 存在显著差异。您需要根据使用情形重写代码,而不是将一个函数调用替换为另一个函数调用。本部分将引导您完成该过程。

如果您的扩展程序是通过政策安装的,则无需进行这些更改。对于通过政策安装的扩展程序,Manifest V3 中仍提供 webRequestBlocking 权限。

这是三个部分中的第二部分,介绍了非扩展服务工作线程的代码所需的更改。本文介绍了如何将 Manifest V2 使用的阻塞式网络请求转换为 Manifest V3 使用的声明式网络请求。其他两个部分介绍了迁移到 Manifest V3 所需的代码更新以及提高安全性

简介

在清单 V2 中,屏蔽 Web 请求可能会严重降低扩展程序的性能以及它们所处理的网页的性能。webRequest 命名空间支持 9 个可能会阻塞的事件,每个事件都可接受无限数量的事件处理程序。更糟糕的是,每个网页都可能被多个扩展程序屏蔽,而实现此目的所需的权限具有侵入性。Manifest V3 通过将回调替换为声明性规则来防范此问题。

更新权限

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

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

您需要根据自己的使用场景添加其他权限。这些权限及其支持的用例如下所述。

创建声明式网络请求规则

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

常见使用场景

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

屏蔽单个网址

在清单 V2 中,一种常见的用例是在后台脚本中使用 onBeforeRequest 事件来阻止 Web 请求。

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

对于清单 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",   ]

重定向多个网址

在清单 V2 中,另一个常见用例是使用 BeforeRequest 事件来重定向 Web 请求。

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 需要在发送网页请求标头之前拦截它们,并移除特定标头。

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" 数组。它支持与之前示例相同的值。

如果您想尝试此操作,可以在我们的示例代码库中找到以下代码

Manifest 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": [     ""   ]