使用 Chrome 扩展拦截并替换 Web 应用程序中的图像

问题描述 投票:0回答:2

我正在尝试编写一个 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

谢谢!

编辑:更新示例代码以反映我在下面的答案。

javascript google-chrome-extension chrome-declarativenetrequest
2个回答
0
投票

我已经设法弄清楚为什么直接请求被重定向,而脚本加载的请求却没有被重定向。我的问题是发起者和主机权限。我一直依赖 Chrome 开发者工具来提供启动器,在上面的示例中,启动器源自 domain2.com。然而,我需要的实际主机权限来自第三个域(称为domain3.com),这似乎是从domain2.com加载脚本的内容的来源。

当我回忆起主机权限允许“”时,我发现了这一点,从长远来看这不是一个好主意,但它确实允许完成重定向。从那里,我的 onRuleMatchedDebug 侦听器可以触发并将重定向的特征记录到控制台,这向我显示了我缺少的正确启动器。

有了我需要的重定向的简明视图,我现在可以将其中一些选项截断为仅实际需要的选项(在原始问题中编辑)。

随后,我想回顾一下开发人员工具中的 HTTP 请求并检查 Referer 标头,其中也有我需要的内容。

所以,撇开愚蠢的疏忽不谈,我想把这个问题再留一会儿,以防有人知道为什么 chrome.declarativeNetRequest.testMatchOutcome 在 Chrome 108.0.5359.72 中似乎不可用,但在 103+ 上有记录。我将其归咎于文档是错误的,但似乎这个功能一定是在某个时候发布的,并且不知何故被错误地删除了?除非有任何见解,否则我可能只是将其作为错误提交。


0
投票

如何使用

chrome.declarativeNetRequest.testMatchOutcom
:

文档

testMatchOutcome、getMatchedRules 和 onRuleMatchedDebug 是 可协助测试规则和规则集。这些API 需要“declarativeNetRequestFeedback”权限。

© www.soinside.com 2019 - 2024. All rights reserved.