2

我无法克服这个问题。有人可以给点建议吗?

  1. 我有这个使用 ExtJS 库的应用程序,我需要在 Chrome 扩展程序中运行它。我已经成功创建了我的消息传递桥 ( postMessage),并将整个应用程序沙盒化在其中,一切正常。ExtJS 已加载,应用程序正在运行。

  2. 然后我有这段逻辑,我需要在我的 ExtJS 视口中预览一段 HTML 片段。我自己创建了一个iframePanel然后afterrender尝试在其中编写代码段。这是我使用的代码:

    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 的框架访问框架。域、协议和端口必须匹配。

  3. 我已经尝试postMessage在沙箱中使用这个动态 iframe,但没有任何反应。在清单中设置sandbox属性也不起作用。这是唯一的方法,并且有效。请看下面我的回答。

问题:

  1. 应该如何设置清单以支持这种用例?
  2. 或者有没有更好的方法来预览 HTML 片段而不使用iframe?Afaik 预览iframe是最好的,因为它将片段沙盒化而不会与父 css 混淆。

笔记

这段代码在 manifest v1 中运行良好,但我计划将其迁移到 manifest v2。我没有意识到内容安全策略 (CSP) 变得如此严格。

一个描述问题的屏幕;)

屏幕

4

1 回答 1

6

对不起,这很尴尬。显然postMessage是唯一的方法,我之前无法让它工作,因为我的 iframe 尚未加载。此外,在 iframe 中访问 dom 文档在 CSP 下是一个很大禁忌,但可以访问contentWindow以执行postMessage.

这就是我为解决这个问题所做的。希望有人能从中受益:

  1. preview.html在您的扩展根目录中创建一个

  2. 在 下manifest.json,将其添加为sandbox属性的一部分

  3. 在 中preview.html,添加以下代码。请注意,我的片段是一个完整的 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>
    
  4. 像往常一样在代码中创建 iframe,将其指向您的preview.html,并将其附加到父 div 或Ext.Panel.

  5. 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}, '*');
    };
    

享受 ;)

编辑

正如迈克在 Chromium 论坛中指出的那样,这个问题也可以解决srcdoc。只需设置 iframe 的 srcdoc 即可解决问题。

只是不确定状态srcdoc

于 2012-09-25T05:09:46.253 回答