0

(交叉张贴在这里

你好,

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

var win = window.open(); win.document.write('<p>Hello!</p>');

这适用于我的扩展程序的背景页面和常规网页,但是当从内容脚本或我的沙盒页面调用时,窗口会打开,但我无法访问 win 对象(它已定义,但为空---console.log 输出“窗户 {}”)。

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

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

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

谢谢,

汉克

4

2 回答 2

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>');
    }
  });
于 2013-02-16T15:29:32.713 回答
0

根据此处的交叉帖子,问题确实在于打开的窗口具有独特的来源。这是有意为之,因为标准工作组 (SWG) 的成员认为,对于继承沙盒起源的 about:blank 页面不做例外处理会更安全。

但是,为了解决这个问题,至少出于我的目的,我可以使用以下方法。首先,忘记沙盒。此解决方法使用嵌入在背景页面中的 iframe,并将 src url 设置为data:text/html,.... 这为 iframe 提供了一个独特的来源,因此它不再位于扩展空间中。这意味着可以使用 eval 而无法访问 chrome api。与沙盒不同,从 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.
    ...
});
于 2013-02-16T16:58:51.917 回答