3

最近谷歌引入了沙盒来增强其安全模型。他们建议使用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

我已经提交了一个错误报告,但不能再等几个月才能有人阅读它,我需要在一个月内使用该应用程序。我该如何解决这个问题?我可以看到使用沙盒iframe的示例仍然有效。有没有办法在不使用 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>
4

2 回答 2

3

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

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

清单.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"
  ]
}

索引.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>

沙盒.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);    
});

背景.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 上的 Chromium 每日构建中测试的:版本 24.0.1309.0 (164508)。这应该与用于 Windows/Mac Canary 构建的版本非常接近,后者本质上也是重新命名的每日构建。

我怀疑您引用的文档(确实建议使用此方法)可能已被弃用。看来谷歌正在朝着不同的方向发展。查看Sandbox Iframe mainpage.js,在与沙盒 iframe 通信时,他们使用了相同的技术,即使用 DOM postMessage API 而不是 Chrome API!

于 2012-10-27T07:59:02.340 回答
1

我只是把这个要点放在一起,它允许 RPC 在sandbox <-> unsandboxed. (也就是说,任何一个都可以公开方法)。

它基于JSON-RPC.

享受!

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

于 2014-01-29T04:55:25.443 回答