简体   繁体   English

web 应用中的图片截取替换为 Chrome 扩展

[英]Intercept and replace images in web app with Chrome extension

I am attempting to write a chrome extension (for personal use) to swap/replace images loaded by a webpage with alternate images.我正在尝试编写一个 chrome 扩展(供个人使用)来交换/替换网页加载的图像和备用图像。 I'd had this working for some time using chrome.webRequest, but am attempting to bring it up-to-speed with manifest v3.我已经使用 chrome.webRequest 进行了一段时间的工作,但我正试图通过 manifest v3 使其与时俱进。

My general solution is that I am hosting my replacement images on my own server, including a script to retrieve as json a list of such images.我的一般解决方案是在我自己的服务器上托管我的替换图像,包括一个脚本来检索 json 此类图像的列表。 I fetch that list and, for each image, create a dynamic redirect rule with chrome.declarativeNetRequest.updateDynamicRules.我获取该列表,并为每个图像使用 chrome.declarativeNetRequest.updateDynamicRules 创建一个动态重定向规则。

This all works beautifully if I request an image to be replaced in a main frame.如果我请求在主框架中替换图像,这一切都会很好地工作。 I can see the successful match with an onRuleMatchedDebug listener, and (of course) the path is dutifully redirected.我可以看到与 onRuleMatchedDebug 侦听器的成功匹配,并且(当然)路径被尽职地重定向。

However, when I load the web app that in turn loads the image (with javascript, presumably with xmlhttprequest?), the redirect rule does not trigger.但是,当我加载 web 应用程序进而加载图像时(使用 javascript,大概使用 xmlhttprequest?),重定向规则不会触发。 The initiator (a javascript source file) is on the same domain and similar path to the images being replaced.启动器(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)});
  });

Again, this DOES all work IF I load a source image directly in chrome, but fails when it's being loaded by the javascript app.同样,如果我直接在 chrome 中加载源图像,这一切都有效,但当它被 javascript 应用程序加载时失败。

I also attempted to test the match by specifying the proper initiator with testMatchOutcome, but my browser seems to claim this API does not exist.我还尝试通过使用 testMatchOutcome 指定正确的启动器来测试匹配,但我的浏览器似乎声称此 API 不存在。 Not at all sure what could be wrong here.完全不确定这里可能出了什么问题。

// 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)); 

I would expect a redirect to "https://myexample.com/files/subdir/image1.png" Instead, I get this error: Uncaught (in promise) TypeError: chrome.declarativeNetRequest.testMatchOutcome is not a function我希望重定向到“https://myexample.com/files/subdir/image1.png”相反,我收到此错误:Uncaught (in promise) TypeError: chrome.declarativeNetRequest.testMatchOutcome is not a function

Documentation https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/#method-testMatchOutcome says it's supported in chrome 103+.文档https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/#method-testMatchOutcome说 chrome 103+ 支持它。 I'm running chrome 108.0.5359.72我正在运行 chrome 108.0.5359.72

Thanks!谢谢!

Edit: Example code updated to reflect my answer below.编辑:更新示例代码以反映我在下面的回答。

I've managed to work out why direct requests were redirected while script loaded ones were not.我已经设法弄清楚为什么直接请求被重定向而脚本加载的请求却没有。 My problem was with the initiator and host permissions.我的问题出在启动器和主机权限上。 I had been relying on Chrome developer tools to provide the initiator, which in the above example originated with domain2.com.我一直依赖 Chrome 开发人员工具来提供启动器,在上面的示例中,它起源于 domain2.com。 However, the actual host permission I needed was from a third domain (call it domain3.com), which seems to be the source of the content that loaded scripts from domain2.com.但是,我需要的实际主机权限来自第三个域(称为 domain3.com),它似乎是从 domain2.com 加载脚本的内容来源。

I discovered this when I recalled that host permissions allows "<all_urls>", which is not a good idea long term, but it did allow the redirects to complete.当我回忆起主机权限允许“<all_urls>”时,我发现了这一点,从长远来看这不是一个好主意,但它确实允许完成重定向。 From there, my onRuleMatchedDebug listener could fire and log to the console the characteristics of the redirect, which showed me the proper initiator I was missing.从那里,我的 onRuleMatchedDebug 侦听器可以触发并将重定向的特征记录到控制台,这向我显示了我缺少的正确启动器。

Having a concise view of the redirects I need, I can now truncate some of these options to only the ones actually needed (edited in original question).有了我需要的重定向的简明视图,我现在可以将其中一些选项截断为仅实际需要的选项(在原始问题中编辑)。

Subsequent to that I thought to look back at the HTTP requests in developer tools and inspect the Referer header, which also had what I was needing.后来想到开发者工具里的HTTP请求,查看Referer header,里面也有我要的。

So, silly oversights aside, I would like to leave this question open a little while longer in case anyone has any idea why chrome.declarativeNetRequest.testMatchOutcome seems unavailable in Chrome 108.0.5359.72 but is documented for 103+.因此,撇开愚蠢的疏忽不谈,我想把这个问题再悬而未决,以防有人知道为什么 chrome.declarativeNetRequest.testMatchOutcome 在 Chrome 108.0.5359.72 中似乎不可用,但在 103+ 上有记录。 I'd chalk it up to the documentation just being wrong, but it seems this function must have shipped at some point and somehow was erroneously removed?我会把它归结为文档错误,但似乎这个 function 必须在某个时候发货并且不知何故被错误地删除了? Barring any insights, I might just submit it as a bug.除非有任何见解,否则我可能只是将其作为错误提交。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM