我正在尝试编写一个 chrome 扩展(供个人使用),以用备用图像交换/替换网页加载的图像。我已经使用 chrome.webRequest 让它工作了一段时间,但我正在尝试使用清单 v3 使其保持最新状态。
我的一般解决方案是在我自己的服务器上托管替换图像,包括一个用于以 json 形式检索此类图像列表的脚本。我获取该列表,并为每个图像创建一个动态重定向规则 chrome.declarativeNetRequest.updateDynamicRules。
如果我请求在主框架中替换图像,这一切都会非常有效。我可以看到与 onRuleMatchedDebug 侦听器的成功匹配,并且(当然)路径被尽职地重定向。
但是,当我加载 Web 应用程序进而加载图像(使用 javascript,大概使用 xmlhttprequest?)时,重定向规则不会触发。启动器(一个 JavaScript 源文件)与被替换的图像位于相同的域和相似的路径中。
//manifest.json
{
"name": "Image replace",
"description": "Replace images in web app",
"version": "2.0",
"manifest_version": 3,
"background": {"service_worker": "background.js"},
"permissions": [
"declarativeNetRequestWithHostAccess",
// "declarativeNetRequestFeedback" // Not necessary once tested
],
"host_permissions" : [
// "https://domain1.com/outerframe/*", // Not necessary
"https://domain2.com/innerframe/*",
"https://domain3.com/*",
"https://myexample.com/*"
]
}
// background.js
//chrome.declarativeNetRequest.onRuleMatchedDebug.addListener((info) => console.log(info)); // Not necessary once tested
var rules = [];
var idx = 1;
fetch("https://myexample.com/list") // returns json list like: ["subdir1\/image1.png", "subdir1\/image2.png", "subdir2\/image1.png"]
.then((response) => response.json())
.then((data) => {
console.log(data);
for (const path of data) {
var src = "https://domain2.com/innerframe/v*/files/" + path; // wildcards a version number
var dst = "https://myexample.com/files/" + path;
rules.push({
"id" : idx++,
"action" : {
"type": "redirect",
"redirect": {
"url": dst
}
},
"condition" : {
"urlFilter": src,
// In the end I only needed main_frame, image, and not xmlhttprequest
"resourceTypes": ["main_frame", "image"]
}
});
}
chrome.declarativeNetRequest.updateDynamicRules({"addRules": rules, "removeRuleIds" : rules.map(r => r.id)});
});
同样,如果我直接在 chrome 中加载源图像,这一切都可以工作,但当它由 javascript 应用程序加载时会失败。
我还尝试通过使用 testMatchOutcome 指定正确的启动器来测试匹配,但我的浏览器似乎声称此 API 不存在。完全不确定这里可能出了什么问题。
// snippet attempted after above updateDynamicRules call
chrome.declarativeNetRequest.testMatchOutcome({
"initiator": "https://domain2.com/innerframe/files/script.js",
"type": "xmlhttprequest",
"url": "https://domain2.com/innerframe/v001/files/subdir/image1.png"
}, (outcome) => console.log(outcome));
我希望重定向到“https://myexample.com/files/subdir/image1.png” 相反,我收到此错误: 未捕获(承诺中)类型错误:chrome.declarativeNetRequest.testMatchOutcome 不是函数
文档 https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/#method-testMatchOutcome 表示 chrome 103+ 支持它。我正在运行 chrome 108.0.5359.72
谢谢!
编辑:更新示例代码以反映我在下面的答案。
我已经设法弄清楚为什么直接请求被重定向,而脚本加载的请求却没有被重定向。我的问题是发起者和主机权限。我一直依赖 Chrome 开发者工具来提供启动器,在上面的示例中,启动器源自 domain2.com。然而,我需要的实际主机权限来自第三个域(称为domain3.com),这似乎是从domain2.com加载脚本的内容的来源。
当我回忆起主机权限允许“
有了我需要的重定向的简明视图,我现在可以将其中一些选项截断为仅实际需要的选项(在原始问题中编辑)。
随后,我想回顾一下开发人员工具中的 HTTP 请求并检查 Referer 标头,其中也有我需要的内容。
所以,撇开愚蠢的疏忽不谈,我想把这个问题再留一会儿,以防有人知道为什么 chrome.declarativeNetRequest.testMatchOutcome 在 Chrome 108.0.5359.72 中似乎不可用,但在 103+ 上有记录。我将其归咎于文档是错误的,但似乎这个功能一定是在某个时候发布的,并且不知何故被错误地删除了?除非有任何见解,否则我可能只是将其作为错误提交。
如何使用
chrome.declarativeNetRequest.testMatchOutcom
:
文档:
testMatchOutcome、getMatchedRules 和 onRuleMatchedDebug 是 可协助测试规则和规则集。这些API 需要“declarativeNetRequestFeedback”权限。