最近,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.1284
和23.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>
答案 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