我想动态地在后台页面中注入并加载iframe。但每次都会取消请求。
http://i.imgur.com/Puto33c.png
一周以前曾经工作过。我不知道我哪里错了。
要重现此问题,我创建了一个小扩展程序:
manifest.js:
{
"name": "iframe background",
"version": "1.0.0",
"manifest_version": 2,
"browser_action": {
"default_title": "iframe"
},
"background": {
"persistent": false,
"scripts": ["background.js"]
}
}
background.js:
chrome.browserAction.onClicked.addListener(function() {
var iframe = document.createElement('iframe');
iframe.src = 'http://localhost:3000/';
iframe.onload = function() {
console.log(iframe.contentDocument); // return null
};
document.body.appendChild(iframe);
});
要加载的页面未被X-Frame-Options SAMEORIGIN阻止。
我试图将iframe直接放在HTML背景页面中,但没有运气。
我还尝试添加content_security_policy:
"content_security_policy": "script-src 'self'; object-src 'self'; frame-src 'self' http://localhost:3000/"
但iframe仍然无法加载。
有人有解决方法或解决此问题吗?
谢谢!
答案 0 :(得分:2)
Chrome 58.0.3014.0 enables Site Isolation for extensions by default,它会在不同的渲染器进程中加载iframe,并由单独的chrome.exe操作系统进程处理。
'取消' message表示扩展程序的chrome.exe进程取消了该请求,它由另一个隐藏的chrome.exe进程处理。
正确的方法是声明一个内容脚本,该脚本将自动在iframe URL上运行并与后台页面进行通信。注意:只能传递JSON可用数据,换句话说,您可以传递innerHTML而不传递DOM元素。这很容易通过DOMParser来处理。
manifest.json补充:
"content_scripts": [{
"matches": ["http://localhost:3000/*"],
"js": ["iframe.js"],
"run_at": "document_end",
"all_frames": true
}],
iframe.js:
var port = chrome.runtime.connect();
// send something immediately
port.postMessage({html: document.documentElement.innerHTML});
// process any further messages from the background page
port.onMessage.addListener(msg => {
..............
// reply
port.postMessage(anyJSONfiableObject); // not DOM elements!
});
background.js:
var iframePort;
chrome.browserAction.onClicked.addListener(() => {
document.body.insertAdjacentHTML('beforeend',
'<iframe src="http://localhost:3000/"></iframe>');
});
chrome.runtime.onConnect.addListener(port => {
// save in a global variable to access it later from other functions
iframePort = port;
port.onMessage.addListener(msg => {
if (msg.html) {
const doc = new DOMParser().parseFromString(msg.html, 'text/html');
console.log(doc);
alert('Received HTML from the iframe, see the console');
}
});
});