动态注入内容脚本 - Chrome 扩展
Dynamically inject content scripts - Chrome Extension
我正在尝试制作一个 chrome 扩展,它从后端接收 javascript 代码并将其保存在 localStorage(作为 base64)中,以便稍后我可以将其作为内容脚本注入加载了正确的页面,除了有几个问题外,它大部分时间都可以工作...第一个问题(不是那么重要)是我无法访问 Chrome API(如 chrome.storage 或 chrome.runtime.sendMessage), 第二个问题是它没有向子 iframe 注入正确的代码...因为 location.href returns 顶部网页的 URL 我找不到在 iframe 本身内访问当前 URL iframe 的方法。
到目前为止,这是我的代码:
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);
}
});
如您所见,我正在尝试重新创建 chrome 在 manifest.json 的 "content_script" 部分中所做的事情,因为我的 javascript 代码是动态的。
注意:我知道 chrome 商店不允许这样做,因此不得与任何人共享此扩展程序。
感谢阅读。
任何帮助将不胜感激。
I cannot access Chrome APIs (like chrome.storage or chrome.runtime.sendMessage)
您的代码当前在后台脚本中生成 page script, not a content script. For the latter you need to use chrome.tabs.executeScript
(see also content script documentation)。
location.href returns the URL of the top webpage and I couldn't find a way to access current URL of iframe within the iframe itself.
不,你所描述的根本不可能发生,这将是对 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
和当然,您将检查 iframe 的真实 URL (frameElement.contentWindow.location.href) 是否不是以 http
开头,因为框架可以在内部导航而无需更改外部的 src
属性.在 try/catch 内部进行检查,因为从不同来源访问 iframe 会抛出异常。
我正在尝试制作一个 chrome 扩展,它从后端接收 javascript 代码并将其保存在 localStorage(作为 base64)中,以便稍后我可以将其作为内容脚本注入加载了正确的页面,除了有几个问题外,它大部分时间都可以工作...第一个问题(不是那么重要)是我无法访问 Chrome API(如 chrome.storage 或 chrome.runtime.sendMessage), 第二个问题是它没有向子 iframe 注入正确的代码...因为 location.href returns 顶部网页的 URL 我找不到在 iframe 本身内访问当前 URL iframe 的方法。
到目前为止,这是我的代码:
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);
}
});
如您所见,我正在尝试重新创建 chrome 在 manifest.json 的 "content_script" 部分中所做的事情,因为我的 javascript 代码是动态的。
注意:我知道 chrome 商店不允许这样做,因此不得与任何人共享此扩展程序。
感谢阅读。 任何帮助将不胜感激。
I cannot access Chrome APIs (like chrome.storage or chrome.runtime.sendMessage)
您的代码当前在后台脚本中生成 page script, not a content script. For the latter you need to use chrome.tabs.executeScript
(see also content script documentation)。
location.href returns the URL of the top webpage and I couldn't find a way to access current URL of iframe within the iframe itself.
不,你所描述的根本不可能发生,这将是对 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
和当然,您将检查 iframe 的真实 URL (frameElement.contentWindow.location.href) 是否不是以 http
开头,因为框架可以在内部导航而无需更改外部的 src
属性.在 try/catch 内部进行检查,因为从不同来源访问 iframe 会抛出异常。