首页 > 解决方案 > 动态注入内容脚本 - Chrome 扩展

问题描述

我正在尝试制作一个 chrome 扩展,它从后端接收 javascript 代码并将其保存在 localStorage(作为 base64)中,以便稍后在加载正确的页面时将其作为内容脚本注入,它在大多数情况下都可以工作,除了有几个问题......第一个问题(不是那么重要)是我无法访问 Chrome API(如 chrome.storage 或 chrome.runtime.sendMessage),第二个问题是它没有向子 iframe 注入正确的代码...因为 location.href 返回顶部网页的 URL,而我找不到在 iframe 本身中访问 iframe 当前 URL 的方法。

到目前为止,这是我的代码:

清单.json

//....
"content_scripts": [{
    "run_at": "document_end",
    "all_frames": true,
    "matches": [
        "<all_urls>"
    ],
    "js": [
        "src/inject/InjectManager.js"
    ]
}],
//...

注入管理器.js:

// Some functions were not included for brevity
chrome.runtime.sendMessage({ action: "get_supported_urls" }, function(supported_urls) {
    let current_url = window.location.href;

    // Check if we support current_url
    let js_code_to_inject = isWebsiteSupported(supported_urls, current_url); // this function returns string that is javascript code.
    if(js_code_to_inject){
        // Append the code to the body
        let script = document.createElement("script");
        script.type = "text/javascript";
        script.innerHTML = js_code_to_inject;

        document.body.appendChild(script);
    }
});

如您所见,我试图重新创建 chrome 在 manifest.json 的“content_script”部分中已经做了什么,因为我的 javascript 代码是动态的。

注意:我知道这在 chrome 商店中是不允许的,因此此扩展程序不得与任何人共享。

谢谢阅读。任何帮助将不胜感激。

标签: javascriptgoogle-chromeiframegoogle-chrome-extensioncontent-script

解决方案


我无法访问 Chrome API(如 chrome.storage 或 chrome.runtime.sendMessage)

您的代码当前制作页面脚本,而不是内容脚本。对于后者,您需要在后台脚本中使用chrome.tabs.executeScript(另请参阅内容脚本文档)。

location.href 返回顶部网页的 URL,我找不到在 iframe 本身中访问 iframe 当前 URL 的方法。

不,您所描述的根本不可能发生,这将是对 URL 源安全性的世界末日级别的违反,因此正在发生其他事情。例如,您的 manifest.json 没有match_about_blank意义 InjectManager.js 根本不处理动态添加的about:blank帧。


清单.json:

"content_scripts": [{
  "match_about_blank": true,
  .....................

注入管理器.js:

chrome.runtime.sendMessage({ action: 'inject', data: location.href });

背景脚本:

chrome.runtime.onMessage.addListener(({ action, data }, sender, sendResponse) => {
  if (action === 'inject') {
    chrome.tabs.executeScript(sender.tab.id, {
      code: getInjectionCode(data),
      frameId: sender.frameId,
    });
  }
});

请注意,某些 iframe 喜欢javascript:srcdoc:根本不会在 Chrome 中运行内容脚本,因此您必须直接在 InjectManager.js 中处理它们,因为它们无法通过 executeScript() 注入。例如,您可以像当前一样使用document.querySelectorAll('iframe')并在其中创建 DOMscript元素来查找所有 iframe,但您将使用frameElement.contentDocument而不是document,当然您将检查 iframe 的真实 URL (frameElement.contentWindow.location.href) 是否启动因为http框架可以在内部导航而不改变它们src在外部的属性。在 try/catch 中进行检查,因为从不同的来源访问 iframe 会抛出异常。


推荐阅读