javascript - 如何与 Chrome 打包 App 中的沙盒窗口通信?

标签 javascript iframe google-chrome-extension security sandbox

最近,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.128423.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/

相关文章:

javascript - 使用 JQuery、Ajax 和 PHP 将数据填充到表中

javascript - 可以将一个对象字面量内的多个属性设置为相同的值吗?

javascript - iframe 如何填充 fancybox

javascript - Chrome 扩展程序 .json 文件上传时出错

c++ - 通讯时 Chrome native 消息错误

javascript - 如何渲染树

javascript - 添加一个类并删除当前类,以便 J Query 中的按钮可以重新用于不同的功能

javascript - 提交长内容的 iframe 表单时,感谢信息不可见,需要向上滚动父级才能看到

javascript - 有没有一种方法可以唯一标识内容脚本在我的 Chrome 扩展程序中运行的 iframe?

javascript - 谷歌浏览器扩展和 Twilio 客户端 API