Search code examples
javascriptwebviewgoogle-chrome-apppostmessage

Communication between Chrome-app and a homepage with PostMessage


I need to be able to send postMessage from a Chrome App through a webview to the homepage and back.

I have established PostMessage from the Chrome App to the homepage, and the PostMessage is also catched by the homepage and a new one is send back, but this PostMessage reply is not caught by the Chrome App.

I can see that it is possible on the Chrome-App API.:

The guest will be able to send replies to the embedder by posting message to event.source on the message event it receives.

So the problem is that i cannot get the Chrome App to catch the reply from the homepage, even though i am using event.source.postMessage('', event.origin) the send the reply with. Is the window.addEventListener('message', messageHandler, false); at the end of background.js wrong ?

I have include the my code below.:

background.js (where the Chrome app is initialized).:

  var myAppWin = null;
  var webview = null;

chrome.app.runtime.onLaunched.addListener(function() {
  // Center window on screen.
  var screenWidth = screen.availWidth/2;
  var screenHeight = screen.availHeight;

  var chromeWindow = chrome.app.window.create('webview-embed.html', {
    id: "helloWorldID",
    bounds: {
      width: screenWidth,
      height: screenHeight,
    }
  }, function(win) {

        myAppWin = win;
        myAppWin.contentWindow.addEventListener('DOMContentLoaded', function() {

          webview = myAppWin.contentWindow.document.getElementById('webview');

          try{
            webview.addEventListener("contentload", function () {

              console.log("webview content is now loaded");

              try{
                console.log("Trying to post message");
                webview.contentWindow.postMessage("Message from Chrome APP!", "*");
              }catch(error){
                console.log("postMessage error: " + error);
              }

            });
          }
          catch(err) {
            console.log("Webview error: " + err);
          }

        });
  });

  //Event listnener for the PostMessage reply    
  var messageHandler = function(event) {
    console.log("got message from page back: " + event.data);
  };
  window.addEventListener('message', messageHandler, false);



});

webview-embed.html (html file with the webview tag).:

<!DOCTYPE html>
<head>
<title>webview</title>
</head>
<body style='margin:0;padding:0;' >
    <webview src="http://localhost" style="width:100%;height:100%;" id="webview" ></webview>
</body>
</html>

index.html (the homepage on the web, that needs to catch the first PostMessage and sent a reply back to the Chrome-app).:

<!DOCTYPE html>
<html lang="en" >
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>title</title>
    </head>
    <body >
    <div id="wrapper" >
        //body
    </div>

    //Used to catch messages from the Chrome App and reply back 
    var messageHandler = function(event) {
      console.log('Message received fom APP!');
      try{
        console.log(event);
        event.source.postMessage("Message from page", event.origin);
        console.log("Sent massage back to APP");
      }catch(error){
        console.log("Error on postMessage back to APP" + error);
      }

    };
    window.addEventListener('message', messageHandler, false);

    </script>
    </body>
</html>

Solution

  • Thanks for the input. Found a solution!

    I made a webview.js and loaded it in webview-embed.html

    var messageHandler = function(event) {
      console.log("Got message from webpage back: " + event.data);
    };
    
    webview = document.getElementById('webview');
    webview.addEventListener("contentload", function () {
      try{
        console.log("Trying to post message");
        webview.contentWindow.postMessage("Message from Chrome APP!", "*");
      }catch(error){
        console.log("postMessage error: " + error);
      }
    
    });
    window.addEventListener('message', messageHandler, false);
    

    Cleaned up my background.js

    chrome.app.runtime.onLaunched.addListener(function() {
      // Center window on screen.
      var screenWidth = screen.availWidth;
      var screenHeight = screen.availHeight;
    
      var chromeWindow = chrome.app.window.create('webview-embed.html', {
        id: "helloWorldID",
        bounds: {
          width: screenWidth,
          height: screenHeight,
        }
      });
    });
    

    and the index.html on the web.:

    <!DOCTYPE html>
    <html lang="en" >
        <head>
            <meta charset="utf-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
            <title>title</title>
        </head>
        <body >
        <div id="wrapper" >
            //body
        </div>
        <script>
        var messageHandler = function(event) {
    
          console.log('Message received fom APP!');
    
          try {
            event.source.postMessage("Message from webpage", "*");
            console.log('message send back to get catched by webview');
          } catch(error) {
            console.log("Error on postMessage back to APP" + error);
          }
    
        };
        window.addEventListener('message', messageHandler, false);
        </script>
        </body>
    </html>