如何与Chrome打包应用中的沙盒窗口进行通信?

时间:2012-10-08 07:50:34

标签: javascript iframe google-chrome-extension security sandbox

最近,Google推出了 sandbox 来增强其安全模型。他们recommend使用 postMessage 作为与沙盒窗口进行通信的方式。但是要发布消息,我需要从后台页面发送第一条消息:

// in background page:
chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', { // index.html is sandboxed
    'width': 800,
    'height': 500
  }, function(myWin) {
      // myWin is ready, I want to post a message
      console.log(myWin); // This is never called after version 23.0.1246, an error is thrown
  });
});

这在版本23.0.1246中运行良好,但不再适用于下一次更新,并且从未返回。现在这种技术会在dev和beta中引发错误(在24.0.128423.0.1271.17上测试)。

我准备了一个显示错误的最小Chrome打包应用程序(在启动应用程序后在后台页面控制台中):https://github.com/losomo/sandbox_test

我已经提交了bug report但是在有人阅读之前已经等了很多个月,我需要在一个月内使用该应用程序。我该如何解决这个问题?我可以看到使用沙盒 iframe examples仍然有效。有没有办法在不使用iframe的情况下使用沙箱,并且仍能与页面进行通信?

这是清单:

{
  "name": "Sandbox test",
  "description": "Sandbox test",
  "manifest_version": 2,
  "minimum_chrome_version": "23",
  "version": "0.0.1",
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  },
  "sandbox": {
     "pages": ["index.html"]
  },
  "permissions": [
    "app.window"
  ]
}

index.html页面:

<!doctype html>
<html lang="cs">
<head>
  <meta charset="UTF-8">
</head>
<body>
    Hi
</body>
</html>

2 个答案:

答案 0 :(得分:3)

可以在Chrome打包应用程序中使用带有弹出窗口的postMessage。但是,您尝试使用的方法仅适用于非沙盒页面,因为您依赖的是受保护的chrome API。

相反,诀窍是使用window.open打开沙盒弹出窗口。更重要的是,这不是一个侥幸,根据这个Chromium Issue,window.open应该在沙盒页面内工作,它确实可以!

<强>的manifest.json:

在清单中,我不确定你是怎么用app.window做的。它没有在Manifest Permissions Documentation中列出,所以我删除了它。此外,您没有启用“后台”权限。我不确定你要做的是否需要它,但如果你需要应用程序在后台运行并且仍然存在,文档确实需要它:

{
  "name": "Sandbox test",
  "description": "Sandbox test",
  "manifest_version": 2,
  "minimum_chrome_version": "21",
  "version": "0.0.1",
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  },
  "sandbox": {
     "pages": ["index.html"]
  },
  "permissions": [
    "background"
  ]
}

<强>的index.html:

请记住,沙盒页面无法访问chrome API,因此我们包含sandbox.js来注册postmessage侦听器。见下一节。

<!doctype html>
<html lang="cs">
<head>
  <meta charset="UTF-8">
  <script type="text/javascript" src="sandbox.js"></script>
</head>
<body>
    Hi. This page is sandboxed and cannot access chrome APIs! 
</body>
</html>

<强> sandbox.js:

此文件包含在index.html页面中:

// register a postmessage listener in index.html sandbox
window.addEventListener("message", function(event) {
    console.info("message received in sandbox: " + event.data.message);    
});

<强> background.js:

请注意,您不能依赖Chrome API与沙盒进行通信!所以我们必须使用window.open而不是chrome.app。* API:

console.log("running in background... waiting for you to click the Sandbox App icon in chrome://newtab");    

// as soon as the launch icon is clicked, this fires
window.addEventListener("DOMContentLoaded", function() {

    // use window.open to create a popup
    sandboxWin = window.open("index.html","SANDBOXED!","height=800,width=500");       

    // fire a postMessage event to the sandbox. Inspect the sandbox and see the 
      // message in the console.
    sandboxWin.postMessage({"message":"It works!!"}, "*");

});

这是在Ubuntu 10.04:版本24.0.1309.0(164508)上的Chromium每日构建上测试的。这应该非常接近用于Windows / Mac Canary版本的版本,这些版本也基本上是重新命名的每日版本。

我怀疑您引用的文档(建议使用此方法)可能会被弃用。谷歌似乎走向了另一个方向。请参阅Sandbox Iframe mainpage.js,在与沙盒iframe通信时,他们使用相同的技术使用DOM postMessage API而不是Chrome API!

答案 1 :(得分:1)

我只是将this gist放在一起,允许在sandbox <-> unsandboxed之间来回传递RPC。 (也就是说,任何一方都可以公开方法)。

它基于JSON-RPC

享受!

另请查看:http://a.shinynew.me/post/37199320546/chrome-packaged-apps-and-the-csp-dilemma