Chrome应用程序和主页之间的PostMessage通信

5
我需要能够从Chrome应用程序通过Webview发送postMessage到主页,然后再返回。
我已经建立了从Chrome应用程序到主页的PostMessage,并且主页也捕获了PostMessage并发送了一个新的回复,但是这个PostMessage回复没有被Chrome应用程序捕获。
我可以看到在Chrome-App API上是可能的。: 来宾将能够通过在收到消息事件上向 event.source 发送消息来向嵌入器发送回复。 所以问题是,即使我使用event.source.postMessage('', event.origin)发送回复,我也无法让Chrome应用程序捕获主页的回复。background.js末尾的window.addEventListener('message', messageHandler, false);是否有误?
我在下面包含了我的代码.: background.js(Chrome应用程序的初始化位置)。
  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(带有webview标签的HTML文件):

<!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(网站首页,需要捕获第一个PostMessage并向Chrome应用程序发送回复)。

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

我还没有诊断整个问题,但其中一部分可能是您在background.js中使用全局变量来保留数据,而在事件页中这样做是行不通的,因为它会根据需要被卸载和重新加载。 (仅记住设置了某些事件处理程序的事实,而不是处理程序本身。) - Marc Rochkind
你需要从后台页面发送和接收消息吗?如果你从应用的主页面发送消息,它应该可以正常工作,即从webview-embed.html的JavaScript中发送。 - lazyboy
@lazyboy,我想在网页上发生事件(收到消息)时制作一个通知,你知道是否有其他方法可以实现吗? - Nederby
如果您拥有页面和扩展程序,则可能是以下情况之一:https://developer.chrome.com/extensions/messaging#external-webpage - lazyboy
1个回答

7

感谢您的反馈。已找到解决方案!

我创建了一个名为webview.js的文件,并将其加载到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);

清理了我的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,
    }
  });
});

在网络上的index.html页面。
<!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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接