javascript - How to communicate with a sandboxed window in Chrome packaged App? - Stack Overflow

admin2025-04-18  0

Recently Google has introduced sandbox to enhance its security model. They remend using postMessage as the way to municate with the sandboxed window. But to post a message I need to send the first message from the background page:

// 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
  });
});

This worked fine in version 23.0.1246 but ceased to work with the next update and has never returned back. Now this technique throws errors in both dev and beta (tested on 24.0.1284 and 23.0.1271.17).

I have prepared a minimal Chrome packaged application that shows the error (in the background page console after launching the app):

I have submitted a bug report but can't wait many more months before someone reads it, I need to use the application within a month. How do I work around this issue? I can see that examples that use sandboxed iframe still work. Is there a way to use a sandbox without using iframes and still be able to municate with the page?

Here is the manifest:

{
  "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"
  ]
}

And the index.html page:

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

Recently Google has introduced sandbox to enhance its security model. They remend using postMessage as the way to municate with the sandboxed window. But to post a message I need to send the first message from the background page:

// 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
  });
});

This worked fine in version 23.0.1246 but ceased to work with the next update and has never returned back. Now this technique throws errors in both dev and beta (tested on 24.0.1284 and 23.0.1271.17).

I have prepared a minimal Chrome packaged application that shows the error (in the background page console after launching the app): https://github./losomo/sandbox_test

I have submitted a bug report but can't wait many more months before someone reads it, I need to use the application within a month. How do I work around this issue? I can see that examples that use sandboxed iframe still work. Is there a way to use a sandbox without using iframes and still be able to municate with the page?

Here is the manifest:

{
  "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"
  ]
}

And the index.html page:

<!doctype html>
<html lang="cs">
<head>
  <meta charset="UTF-8">
</head>
<body>
    Hi
</body>
</html>
Share Improve this question edited Oct 27, 2012 at 8:03 jamesmortensen 34.1k11 gold badges102 silver badges124 bronze badges asked Oct 8, 2012 at 7:50 hlidkahlidka 2,3651 gold badge18 silver badges15 bronze badges 2
  • You get this figured out? Where are you actually making the postMessage request. I don't see that in your code. Consider adding via this edit link. Also, please post your manifest file. Good luck! – jamesmortensen Commented Oct 26, 2012 at 20:36
  • Manifest file is in the example. The postMessage should be instead of the line with console.log(myWin);, there is just this to show that the code is not even reachable. – hlidka Commented Oct 27, 2012 at 6:03
Add a ment  | 

2 Answers 2

Reset to default 4

It is possible to use postMessage with a popup window in a Chrome Packaged App. However, the method that you're attempting to use will only work with non-sandboxed pages, since you're relying on the chrome APIs, which are protected.

Instead, the trick is to use window.open to open the sandboxed popup window. What's more, this isn't a fluke, according to this Chromium Issue, window.open should work inside sandboxed pages, and it does!

manifest.json:

In the manifest, I'm not sure what you were trying to do with app.window. It's not listed in the Manifest Permissions Documentation, so I removed it. Also, you didn't have the "background" permission enabled. I'm not sure if it's required for what you're trying to do, but the documentation does call for it if you need the app to run in the background and persist:

{
  "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:

Remember, sandboxed pages can't access chrome APIs, so we include sandbox.js to register a postmessage listener. See next section.

<!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:

This file is included in the index.html page:

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

background.js:

Remember, you can't rely on Chrome API's to municate with a sandbox! So we must use window.open instead of chrome.app.* APIs:

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!!"}, "*");

});

This was tested on a Chromium daily build on Ubuntu 10.04: Version 24.0.1309.0 (164508). This should be very close to the version used for the Windows/Mac Canary builds, which are also essentially rebranded daily builds.

I suspect the docs you've cited, which do suggest using this method, may be deprecated. It appears Google is going a different direction. See the Sandbox Iframe mainpage.js, where they use the same technique of using the DOM postMessage API instead of the Chrome APIs when municating with sandboxed iframes!

I just put this gist together which allows for RPC back and forth between sandbox <-> unsandboxed. (That is, either one can expose methods).

It is based on JSON-RPC.

Enjoy!

Also check out: http://a.shinynew.me/post/37199320546/chrome-packaged-apps-and-the-csp-dilemma

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744965165a277152.html

最新回复(0)