从Google Chrome扩展程序沙箱页面打开并写入新窗口

时间:2013-02-15 14:34:52

标签: google-chrome-extension

(交叉发布here

您好,

我有一个沙盒页面(在我的清单中指定),它在我的扩展程序的后台页面中加载到iframe中。在我的沙盒页面中,我想打开一个新窗口并写入它,即:

var win = window.open(); win.document.write( '< P&安培; gtHello<!/ p为H.');

这可以从我的扩展程序的后台页面和常规网页中使用,但是当从内容脚本或我的沙盒页面调用时,窗口会打开,但是我无法访问win对象(它是已定义的,但是空的---控制台。日志输出“Window {}”)。

我认为这是由于同源策略(每个窗口都在沙盒环境中被赋予了一个uinque-origin)。但是,由于窗口打开一个about:空白页面,我很困惑为什么这很重要。

这是一个功能吗?是否有一个参数可以添加到我的清单中以避免这种情况?有没有人知道不使用postMessage回到我的后台页面的解决方法?我理想的解决方案是让我的沙盒脚本打开一个新窗口并直接与它进行交互,而不是通过消息传递。

如果有必要,我可以提供一个完整的例子,但我希望有人可能只是知道他们的头脑。我在Mac上运行Chrome 24.0.1312.57,在Ubuntu上运行24.0.1312.68,如果有帮助的话。

谢谢,

汉克

2 个答案:

答案 0 :(得分:0)

根据定义,内容脚本是您加载的外部常规网页的一部分,因此我不确定您的脚本如何在“常规网页”上工作,而不是内容脚本。您是说代码在您自己的页面中嵌入时有效,而不是通过内容脚本在其他页面中嵌入?

无论如何,如果脚本在您的后台页面中正常运行,您可以随时尝试发送消息。 (更多这里:http://developer.chrome.com/extensions/messaging.html

沙盒/内容脚本的脚本:

//send message to background page
chrome.extension.sendMessage({todo: "newWindow"}); 

在后台页面中:

//create a listener
chrome.extension.onMessage.addListener(
  function(request, sender) {   
    if (request.todo === "newWindow") {
    //do your stuff here
        var win = window.open(); win.document.write('<p&gtHello!</p>');
    }
  });

答案 1 :(得分:0)

根据交叉发布here,问题确实是打开的窗口具有唯一的来源。这是故意的,因为标准工作组(SWG)的成员认为,对于以下内容不做例外更安全:空白页面继承了沙盒的来源。

但是,为了解决这个问题,至少为了我的目的,我可以使用以下方法。首先,忘记沙箱。此解决方法使用嵌入在后台页面中的iframe,其中src url设置为data:text/html,...。这为iframe提供了唯一的原点,因此它不再位于扩展空间中。这意味着可以使用eval并且无法访问chrome apis。与沙箱不同,从iframe打开的窗口与iframe共享同一个源,允许访问创建的窗口。例如:

在后台html页面中:

<html>
<head>
    ...
    <script src="background.js"></script>
    ...
</head>
<body>
    ...
    <iframe id="myframe"></iframe>
    ...
</body>
</html>

在background.js中:

...
document.getElementById('myframe').setAttribute('src', 'data:text/html,'+ 
    encodeURI('<html><head>'+
    '<script src='+chrome.extension.getURL('jquery.js')+'></script>'+
    '<script src='+chrome.extension.getURL('myscript.js')+'></script>'+
    ...
    '</head><body></body></html>'
));
...

在myscript.js中

jQuery(document).ready(function(){
    ...
    // To receive messages from background.js.
    window.addEventListener('message', function(e){ ... } );

    // To send messages to background.js.
    parent.postMessage({...}, '*');

    // To open AND ACCESS a window.
    var win = window.open();
    win.document.write('Hello'); // Fails in sandbox, works here.

    // Eval code, if you want. Can't do this from an extension
    // page loaded normally unless you allow eval in your manifest.
    // Here, it's okay!
    eval( 'var x = window.open(); x.document.write("Hi!")' );

    // No chrome apis.
    chrome.log( chrome.extension ); // -> undefined
    chrome.log( chrome.windows ); // -> undefined

    // No direct access to background page (e.g., parent).
    chrome.log( parent ); // -> Window with no properties.
    ...
});