我正在尝试创建一个chrome扩展程序,该扩展程序从后端接收javascript代码并将其保存在localStorage中(作为base64),以便以后可以在加载正确的页面时将其作为内容脚本注入,它确实可以除了几个问题以外的时间...第一个问题(不是很重要)是我无法访问Chrome API(例如chrome.storage或chrome.runtime.sendMessage),第二个问题是它没有注入正确的代码子iframe ......,因为location.href返回顶部网页的URL,但是我找不到在iframe本身内访问iframe当前URL的方法。
到目前为止,这是我的代码:
manifest.json
//....
"content_scripts": [{
"run_at": "document_end",
"all_frames": true,
"matches": [
"<all_urls>"
],
"js": [
"src/inject/InjectManager.js"
]
}],
//...
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);
}
});
如您所见,由于我的JavaScript代码是动态的,因此我正在尝试重新创建chrome在manifest.json的“ content_script”部分中已经执行的操作。
注意:我知道Chrome商店不允许这样做,因此,此扩展名不得与任何人共享。
感谢您的阅读。 任何帮助将不胜感激。
答案 0 :(得分:1)
我无法访问Chrome API(例如chrome.storage或chrome.runtime.sendMessage)
您的代码当前生成page script,而不是内容脚本。对于后者,您需要在后台脚本中使用chrome.tabs.executeScript
(另请参见content script documentation)。
location.href返回顶部网页的URL,但我找不到在iframe本身内访问iframe当前URL的方法。
不,您所描述的完全不可能发生,这将是世界末日级别对URL来源安全性的违反,因此正在发生其他事情。例如,您的manifest.json没有match_about_blank
,意味着InjectManager.js根本不处理动态添加的about:blank
框架。
manifest.json:
"content_scripts": [{
"match_about_blank": true,
.....................
InjectManager.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,
});
}
});
请注意,某些javascript:
或srcdoc:
等iframe根本不会在Chrome中运行内容脚本,因此您必须直接在InjectManager.js中对其进行处理,因为executeScript无法将其注入( )。例如,您可以使用document.querySelectorAll('iframe')
查找所有iframe,并像现在一样在其中创建DOM script
元素,但是您将使用frameElement.contentDocument
而不是document
,当然, ll检查iframe的真实URL(frameElement.contentWindow.location.href)是否不以http
开头,因为可以在内部导航框架而无需在外部更改其src
属性。在try / catch内进行检查,因为从其他来源访问iframe会抛出该错误。