Chrome扩展程序:将内容写入沙盒环境中创建的动态iframe

Lio*_*han 2 javascript iframe google-chrome postmessage google-chrome-extension

我无法克服这个问题.有人可以提一些建议吗?

  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);
    
    Run Code Online (Sandbox Code Playgroud)

    那么错误:

    不安全的JavaScript尝试访问具有以下URL的URL的框架:带有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)已经变得严格.

一个描述问题的屏幕;)

屏幕

Lio*_*han 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>
    
    Run Code Online (Sandbox Code Playgroud)
  4. 像往常一样在代码中创建iframe preview.html,将其指向您的iframe ,并将其附加到父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}, '*');
    };
    
    Run Code Online (Sandbox Code Playgroud)

请享用 ;)

编辑

正如Mike在Chromium论坛上指出的那样,这个问题也可以解决srcdoc.只需设置iframe的srcdoc,问题就解决了.

只是不确定的状态 srcdoc