最近,Google 引入了沙盒 来增强其安全模型。他们 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
中运行良好,但在下一次更新时停止工作并且再也没有返回。现在,此技术会在开发和测试版中引发错误(在 24.0.1284
和 23.0.1271.17
上测试)。
我准备了一个显示错误的最小 Chrome 打包应用程序(在启动应用程序后在后台页面控制台中):https://github.com/losomo/sandbox_test
我已经提交了 bug report但不能再等几个月才有人阅读它,我需要在一个月内使用该应用程序。我该如何解决这个问题?我可以看到 examples使用沙盒 iframe 仍然有效。有没有办法在不使用 iframe 的情况下使用沙箱并且仍然能够与页面通信?
这是 list :
{
"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>
最佳答案
可以在 Chrome 打包应用程序中使用带有弹出窗口的 postMessage。但是,您尝试使用的方法仅适用于非沙盒页面,因为您依赖于 protected chrome API。
相反,诀窍是使用 window.open 打开沙盒弹出窗口。更重要的是,这不是侥幸,根据这个 Chromium Issue , window.open 应该在沙盒页面中工作,确实如此!
list .json:
在 list 中,我不确定您尝试使用 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 来注册一个消息后监听器。请参阅下一节。
<!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);
});
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 上的 Chromium 日常构建上测试的:版本 24.0.1309.0 (164508)。这应该与用于 Windows/Mac Canary 构建的版本非常接近,后者本质上也是重新命名的日常构建。
我怀疑您引用的文档中确实建议使用此方法,但可能已被弃用。看来谷歌正朝着不同的方向发展。查看Sandbox Iframe mainpage.js ,在与沙盒 iframe 通信时,他们使用相同的技术,即使用 DOM postMessage API 而不是 Chrome API!
关于javascript - 如何与 Chrome 打包 App 中的沙盒窗口通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12777434/