简体   繁体   English

Chrome 扩展 - 包含 XHR 猴子补丁的内容脚本运行速度太慢并且错过了初始请求

[英]Chrome Extension - Content script containing XHR monkey patch runs too slowly and misses initial requests

I have a chrome extension that is meant to intercept response body data, manipulate it into useful statistics and then render these stats on the page.我有一个 chrome 扩展,旨在拦截响应正文数据,将其处理为有用的统计信息,然后在页面上呈现这些统计信息。

The problem is that the request interceptor loads after the most important requests have already been sent/received so is unable to scrape them (see my attached images from the chrome network tab hopefully that'll make things clearer).问题是请求拦截器在最重要的请求已经发送/接收后加载,因此无法抓取它们(请参阅我在 chrome 网络选项卡中附加的图像,希望这会使事情更清楚)。

Currently, my interceptor runs in a content.js script that is matched to the urls I'm interested in.目前,我的拦截器在与我感兴趣的 url 匹配的 content.js 脚本中运行。


INTERCEPTOR.JS拦截器.JS

listenerFn = (event) => {
    console.log("Url:, ", event.target.responseURL);
    // DO OTHER STUFF
}

(
    () => {
        var XHR = XMLHttpRequest.prototype;
        var send = XHR.send;
        XHR.send = function() {
            this.addEventListener('load', listenerFn)
            return send.apply(this, arguments);
        };
    }
)();

My manifest (V3) script looks like this...我的清单(V3)脚本看起来像这样......


MANIFEST.JSON清单.JSON

{
    "manifest_version": 3,
    .....
    "background": {
        "service_worker": "background.js"
    },
    "content_scripts": [
        {
          "matches": ["URL_OF_INTEREST.com/*"],
          "js": ["interceptor.js"],
          "run_at": "document_start"
        }
    ],
    "web_accessible_resources": [
        {
            "matches": ["<all_urls>"],
            "resources": ["interceptor.js"]
        }
    ],
    "permissions": [
        "scripting",
        "activeTab",
        "declarativeContent",
        "storage",
        "tabs"
    ],
    "host_permissions": [
        "*://*/*"
      ]
}

I feel like my options are either:我觉得我的选择是:

  1. Work out how to inject the interceptor script faster研究如何更快地注入拦截器脚本
  2. Delay page requests until the interceptor has been fully injected (impossible?)延迟页面请求,直到拦截器被完全注入(不可能?)
  3. Try using chrome.WebRequest somehow尝试以某种方式使用 chrome.WebRequest

I don't know if any of these are possible.我不知道这些是否可行。 1 - I don't think the interceptor can be injected sooner in the current setup (as i think I've done all I can with setting run_at). 1 - 我认为在当前设置中不能更快地注入拦截器(因为我认为我已经尽我所能设置 run_at)。 2 - I dont even know if this can be done. 2 - 我什至不知道这是否可以做到。 3 - I believe WebRequest doesn't give access to request bodys. 3 - 我相信 WebRequest 不能访问请求正文。

Someone mentioned to me that as the code is not related to page content it may be possible to have this code run in the background.js script.有人向我提到,由于代码与页面内容无关,因此可以在 background.js 脚本中运行此代码。 So maybe this is a good avenue to explore.所以也许这是一个很好的探索途径。

I've attached two images below showing the network tab from chrome dev tools.我在下面附上了两张图片,显示了 chrome 开发工具中的网络选项卡。

In the first image (which shows only XHRs), the green arrow is the request that I need to scrape, the purple bracket covers requests that haven't been intercepted and the yellow ones are requests that have.在第一张图片(仅显示 XHR)中,绿色箭头是我需要抓取的请求,紫色括号涵盖尚未被拦截的请求,黄色是已拦截的请求。 The colours are similar in the second image (which shows both XHRs and JS files), but this includes a blue arrow showing when the interceptor.js file has been run.第二张图片中的颜色相似(显示 XHR 和 JS 文件),但其中包含一个蓝色箭头,显示拦截器.js 文件何时运行。

网络截图(仅限 XHR) 网络截图(XHR 和 JS 文件)

Any suggestions or guidance would be greatly appreciated.任何建议或指导将不胜感激。 If anyone wants/requires any additional information just let me know,如果有人想要/需要任何其他信息,请告诉我,

Thanks!谢谢!

Assuming your injector script is loaded via DOM script element's src , it loads asynchronously and runs after the other scripts loaded by the page.假设您的注入器脚本是通过 DOM script元素的src加载的,它会异步加载并在页面加载的其他脚本之后运行。 The solution is to register this script using chrome.scripting.registerContentScripts in MAIN world.解决方案是在MAIN世界中使用chrome.scripting.registerContentScripts注册此脚本。

  1. Remove web_accessible_resources and the code in the content script that loads interceptor.js移除web_accessible_resources和内容脚本中加载interceptor.js 的代码

  2. Add the following code to your background.js:将以下代码添加到您的 background.js:

     chrome.runtime.onInstalled.addListener(async () => { const scripts = [{ id: 'interceptor', js: ['interceptor.js'], matches: ['<all_urls>'], runAt: 'document_start', world: 'MAIN', }]; const ids = scripts.map(s => s.id); await chrome.scripting.unregisterContentScripts({ids}).catch(() => {}); await chrome.scripting.registerContentScripts(scripts).catch(() => {}); });

Another problem is that you load the same file in content_scripts and web_accessible_resources .另一个问题是您在content_scriptsweb_accessible_resources中加载了相同的文件。 You should use two different scripts because they run in two different contexts ("worlds").您应该使用两个不同的脚本,因为它们在两个不同的上下文(“世界”)中运行。 To communicate between them you can use CustomEvent messaging ( example ).要在它们之间进行通信,您可以使用 CustomEvent 消息传递(示例)。

And lastly, the site may be using iframes to make the requests, in which case you need to add "all_frames": true to your content script's declaration in manifest.json, and possibly "match_origin_as_fallback": true in case the iframe is about:blank or doesn't have any src .最后,该站点可能正在使用 iframe 发出请求,在这种情况下,您需要在 manifest.json 中的内容脚本声明中添加"all_frames": true "match_origin_as_fallback": true ,如果 iframe 是about:blank或没有任何src

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

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