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 请求。
chrome.webRequest.onBeforeRequest.addListener((e) => { return { cancel: true }; }, { urls: ["https://www.example.com/*"] }, ["blocking"]);
对于清单 V3,请使用 "block" 操作类型创建新的 declarativeNetRequest 规则。请注意示例规则中的 "condition" 对象。其 "urlFilter" 会替换传递给 webRequest 监听器的 urls 选项。"resourceTypes" 数组用于指定要屏蔽的资源类别。此示例仅屏蔽主 HTML 网页,但您也可以仅屏蔽字体。
[ { "id" : 1, "priority": 1, "action" : { "type" : "block" }, "condition" : { "urlFilter" : "||example.com", "resourceTypes" : ["main_frame"] } } ]
为了使此功能正常运行,您需要更新扩展程序的权限。在 manifest.json 中,将 "webRequestBlocking" 权限替换为 "declarativeNetRequest" 权限。请注意,网址已从 "permissions" 字段中移除,因为屏蔽内容不需要主机权限。如上所示,规则文件指定了声明性网络请求所应用的主机。
如果您想尝试此操作,可以在我们的示例代码库中找到以下代码。
"permissions": [ "webRequestBlocking", "https://*.example.com/*" ]
"permissions": [ "declarativeNetRequest", ]
重定向多个网址
在清单 V2 中,另一个常见用例是使用 BeforeRequest 事件来重定向 Web 请求。
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" 字段,其中包含要返回的网址,而不是要过滤的网址。
[ { "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" 权限。
如果您想尝试此操作,可以在我们的示例代码库中找到以下代码。
"permissions": [ "webRequestBlocking", "https://developer.chrome.com/docs/extensions/*", "https://developer.chrome.com/docs/extensions/reference" ]
"permissions": [ "declarativeNetRequestWithHostAccess" ], "host_permissions": [ "https://developer.chrome.com/*" ]
屏蔽 Cookie
在 Manifest V2 中,屏蔽 Cookie 需要在发送网页请求标头之前拦截它们,并移除特定标头。
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" 数组。它支持与之前示例相同的值。
如果您想尝试此操作,可以在我们的示例代码库中找到以下代码。
[ { "id": 1, "priority": 1, "action": { "type": "modifyHeaders", "requestHeaders": [ { "header": "cookie", "operation": "remove" } ] }, "condition": { "urlFilter": "|*?no-cookies=1", "resourceTypes": ["main_frame"] } } ]
此方案还需要更改扩展程序的权限。与之前一样,将 "webRequestBlocking" 权限替换为 "declarativeNetRequest" 权限。
"permissions": [ "webRequest", "webRequestBlocking", "https://*/*", "http://*/*" ],
"permissions": [ "declarativeNetRequest", ], "host_permissions": [ "" ]