Javascript 动态注入内容脚本-Chrome扩展
我正在尝试创建一个chrome扩展,它从后端接收javascript代码并将其保存在localStorage(作为base64)中,以便稍后在加载正确的页面时将其作为内容脚本注入,它在大多数情况下都可以工作,但有一些问题。。。第一个问题(不是那么重要)是我无法访问ChromeAPI(如Chrome.storage或Chrome.runtime.sendMessage),第二个问题是它没有将正确的代码注入子iFrame。。。因为location.href返回顶部网页的URL,而我无法在iframe本身中找到访问iframe当前URL的方法 这是我目前的代码: manifest.jsonJavascript 动态注入内容脚本-Chrome扩展,javascript,google-chrome,iframe,google-chrome-extension,content-script,Javascript,Google Chrome,Iframe,Google Chrome Extension,Content Script,我正在尝试创建一个chrome扩展,它从后端接收javascript代码并将其保存在localStorage(作为base64)中,以便稍后在加载正确的页面时将其作为内容脚本注入,它在大多数情况下都可以工作,但有一些问题。。。第一个问题(不是那么重要)是我无法访问ChromeAPI(如Chrome.storage或Chrome.runtime.sendMessage),第二个问题是它没有将正确的代码注入子iFrame。。。因为location.href返回顶部网页的URL,而我无法在iframe
//....
"content_scripts": [{
"run_at": "document_end",
"all_frames": true,
"matches": [
"<all_urls>"
],
"js": [
"src/inject/InjectManager.js"
]
}],
//...
如您所见,我正在尝试重新创建chrome在manifest.json的“content_script”部分中已经做过的事情,因为我的javascript代码是动态的
注意:我知道这是不允许在chrome商店上使用的,因此,此扩展不能与任何人共享
谢谢你的阅读。
任何帮助都将不胜感激
我无法访问ChromeAPI(如Chrome.storage或Chrome.runtime.sendMessage)
您的代码当前生成一个脚本,而不是一个内容脚本。对于后者,您需要在后台脚本中使用chrome.tabs.executeScript
(另请参见)
location.href返回顶部网页的URL,但我无法在iframe本身中找到访问iframe当前URL的方法
不,您所描述的根本不可能发生,这将是对URL源安全的世界末日级别的违反,所以发生了其他事情。例如,manifest.json没有match\u about\u blank
意味着InjectManager.js根本不处理动态添加的about:blank
帧
manifest.json:
"content_scripts": [{
"match_about_blank": true,
.....................
InjectManager.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.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')
查找所有iframe,并像当前一样在内部创建DOMscript
元素,但您将使用frameElement.contentDocument
而不是document
,当然,您将检查iframe是否是真正的URL(frameElement.contentWindow.location.href)不要以http
开头,因为框架可以在内部导航,而无需更改其外部的src
属性。请执行内部检查try/catch,因为从不同来源访问iframe会引发错误。感谢您的回答,这帮了大忙。我不知道存在executeScript,它现在工作得更好了。我尽管@wOxxOm,关于你的最后一个注释还有一个问题:我不希望我的脚本被注入javascript:或srcdoc:iframes,我只希望它在“real”中运行有实际URL的iframe,我需要一种方法来获取该URL,以检查我是否要注入其中,因为当前location.href确实返回与父网站相同的URL…另外需要注意的是,我正在测试的iframe是空的,并且有src='javascript:false',记录frameElement.contentWindow.locationiframe上的.href也返回父URL(我想要返回javascript:false的内容).我说得通吗?web安全性基于URL来源。您看到的是同一来源iframe-所有那些javascript:
,关于:
,srcdoc:
没有沙盒属性的框架与嵌入框架/页面运行在同一来源,这就是为什么它们的URL是相同的。有没有办法检查那些类型的框架?我不想注入它们…只是不添加match\u about\u blank
。Chrome无论如何不会注入javascript:
。要检查iframe是否是相同的源代码,您还可以尝试访问属于父窗口的内容:让isSame;尝试{isSame=!!window.frameElement}捕获(e){}