【问题标题】:Chrome extension: writing content into a dynamic iframe created in a sandboxed environmentChrome 扩展:将内容写入在沙盒环境中创建的动态 iframe
【发布时间】:2012-09-24 08:58:45
【问题描述】:
我无法克服这个问题。谁能给点建议?
我有这个使用 ExtJS 库的应用程序,我需要在 Chrome 扩展程序中运行它。我已经成功创建了我的消息传递桥 (postMessage),并将整个应用程序沙盒化在其中,一切正常。 ExtJS 已加载,应用程序正在运行。
-
然后我有了这个逻辑,我需要在我的 ExtJS 视口中预览一段 HTML sn-ps。我在Panel 本身和afterrender 上创建了一个iframe,我尝试在其中编写sn-p。这是我使用的代码:
html: '<iframe src="about:blank" style="width:100%;height:100%;border:none;"></iframe>';
......
//p is the panel found in afterrender
p.body.down('iframe').dom.contentDocument.write(content);
然后报错:
不安全的 JavaScript 尝试使用 URL about:blank 从 URL chrome-extension://fcnpmlgapilgclcelfanblpbglmkghbc/core/themes/default/app.html 访问框架。域、协议和端口必须匹配。
我已经尝试在沙箱中使用postMessage 到此动态 iframe,但没有任何反应。在清单中设置sandbox 属性也不起作用。 这是唯一的方法,它有效。请参阅下面的答案。
问题:
- 应该如何设置清单来支持这种用例?
- 或者有没有更好的方法来预览 HTML sn-p 而不使用
iframe?使用 iframe 进行 Afaik 预览是最好的,因为它将 sn-p 沙盒化而不会与父 css 混淆。
注意
这段代码在清单 v1 中运行良好,但我计划将其迁移到清单 v2。没想到内容安全政策 (CSP) 变得如此严格。
描述问题的屏幕;)
【问题讨论】:
标签:
javascript
google-chrome
iframe
google-chrome-extension
postmessage
【解决方案1】:
对不起,这很尴尬。显然postMessage 是唯一的方法,我之前无法让它工作,因为我的 iframe 尚未加载。此外,在 iframe 中访问 dom 文档在 CSP 下是一个很大的否,但可以访问 contentWindow 来执行 postMessage。
这就是我为解决这个问题所做的。希望有人能从中受益:
在您的扩展根目录中创建preview.html
在manifest.json 下,将其添加为sandbox 属性的一部分
-
在preview.html 内,添加以下代码。请注意,我的 sn-p 是一个完整的 html,所以我使用了document.write。
<!DOCTYPE html>
<html>
<head>
<script>
window.addEventListener("message", function(e) {
if (e.data.content) {
document.write(e.data.content);
}
});
</script>
</head>
<body></body>
</html>
像往常一样在代码中创建 iframe,将其指向您的 preview.html,并将其附加到父 div 或 Ext.Panel。
-
在元素被绘制/创建/附加后,使用以下代码postMessage。
var content = '<!DOCTYPE html><html><body>Hello World!</body></html>';
var iframe = p.body.down('iframe').dom; //or the iframe node
iframe.onload = function() {
iframe.contentWindow.postMessage({content: content}, '*');
};
享受;)
编辑
正如Mike in Chromium forum 所指出的,这个问题也可以通过srcdoc 解决。只需设置 iframe 的 srcdoc 即可解决问题。
只是不确定srcdoc的状态