javascript - 动态注入内容脚本 - 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 商店中是不允许的,因此此扩展程序不得与任何人共享。
谢谢阅读。任何帮助将不胜感激。
解决方案
我无法访问 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 会抛出异常。
推荐阅读
- mapbox - 如何使用 csv2geojson 数据添加标记而不是圆圈
- python - 如何在没有 IronPython 的情况下将 C#(winforms 应用程序)、当前文本框文本传递给 Python 变量
- spring-data-jpa - QueryDSL 表达式正在抛出 *java.lang.UnsupportedOperationException: null* 异常
- c++ - 如何预编译不以 .h 结尾的 C++ 头文件
- java - 无法转换名称为 org.apache.hadoop.fs.FileSystem$Cache 的类。原因:org.apache.hadoop.fs.FileSystem$Cache$Key 类被冻结
- c# - Microsoft Visual Studio 显示“Table 一词附近使用了不正确的语法”
- c# - 在 .Net 中使用 Web API 和 Windows 应用程序上传文件
- ef-code-first - ef core 一对多共享子表
- c# - 无法构建 Uno Platform UWP 模板项目
- selenium - 在 Flutter Web 应用中使用 Selenium 浏览器测试的策略