如何在Chrome App中与WebView进行通信? [英] How to communicate with WebView in Chrome App?

查看:219
本文介绍了如何在Chrome App中与WebView进行通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开发了一个网站,我打算在Chrome应用程序中的web视图中显示。这工作正常。



现在,我想从网站使用postMessage,将消息从webview发送到包含的Chrome应用程序。这是通过webview中的 top.postMessage 来完成的。



我尝试了以下事件侦听器: p>

  webView.contentWindow.addEventListener('message',messageHandler); 

webView.addEventListener('message',messageHandler);

window.addEventListener('message',messageHandler);

document.addEventListener('message',messageHandler);

我成功实现了以下事件侦听器。所有这些都按预期工作: contentload 对话框 consolemessage

除非我可以得到这个工作,我正在考虑使用 consolemessage 将消息从webview发送到这个容器 - 我觉得没什么吸引力,我怀疑它不会在不使用开发者模式的时候工作。

解释方案

嵌入式网页无法将消息发布到应用程序,这是因为嵌入式网页没有对应用程序的引用。



top.postMessage 不是对应用程序的引用。 top 在您尝试在同一个webview中访问最上面的框架时可以使用。



为了能够发送消息到应用程序,网页需要对应用程序的引用。最简单的方法是让应用程序发送第一条消息到框架 - hello - 消息。



从应用程序:

  //初始化通信
webView.contentWindow.postMessage('hello,webpage!','https://your.web。页/*');
addEventListener('message',function(e){

//我希望这个检查能够正常工作,但是我没有测试过它
if(e.source!= webView.contentWindow)
return;

//然后处理e.data。
});

在网页中:

  var messageSource,messageOrigin; 
addEventListener('message',function(e){
if(!messageSource){
$ b $ * / $
*一旦我们有了一个messageSource,我们就不应该允许(e.data ==hello,webpage!){

/ * $($) b $ b *如果可能的话,你应该在这里验证`e.origin`的值,可能
*可能来自其他地方,然而,这是非常安全的,因为它是
*是一个非常狭窄的时间窗口,应用程序
*打开时愿意接受hello,webpage!消息。
*
*验证的另一种方式是让应用程序等待
*hello,host!消息如果在第二个
*内没有收到响应,则应用程序主机可以简单地重新加载应用程序
* /

messageSource = e.source;
messageOrigin = e.origin;
messageSource.postMessage(hello,host!,messageOrigin);
}
} else {
//不管你喜欢如何处理消息。这只会响应每条消息:
messageSource.postMessage('Your message:'+ e.data,messageOrigin);
}
});


I have developed a website which I intend to display inside a webview, within a Chrome App. This works fine.

Now, I want to use postMessage from the website, to send messages out of the webview and into the containing Chrome App. This is done via top.postMessage inside the webview.

I've tried the following event listeners:

webView.contentWindow.addEventListener('message', messageHandler);

webView.addEventListener('message', messageHandler);

window.addEventListener('message', messageHandler);

document.addEventListener('message', messageHandler);

I have successfully implemented the following event listeners. All of which work as expected: contentload, dialog and consolemessage.

Unless I can get this to work, I am considering using consolemessage to send messages from the webview to the container - something I find unappealing, and I suspect it won't work when not using the developer mode.

解决方案

The reason that the embedded web page is unable to post messages to the app, is because the embedded web page does not have a reference to the app.

top.postMessage is not a reference to the app. top would work if you were trying to access the topmost frame, within the same webview.

To be able to send messages to the app, the web page needs a reference to the app. The easiest way to do this, is by having the app send the first message to the frame - a "hello"-message.

From the app:

// Initialize communications
webView.contentWindow.postMessage('hello, webpage!', 'https://your.web.page/*');
addEventListener('message', function(e) {

    // I expect this check to work, but I have not tested it.
    if (e.source != webView.contentWindow)
        return;

    // Handle e.data however you want.
});

In the web page:

var messageSource, messageOrigin;
addEventListener('message', function(e) {
    if (!messageSource) {

        /*
         * Once we have a messageSource, we should not allow anybody to change
         * messageSource again
         */

        if (e.data == "hello, webpage!") {

            /*
             * If possible, you should validate the `e.origin` value here. It could 
             * possibly come from somewhere else. However, this is quite safe as it 
             * stands, since there only is a very narrow time window where the app 
             * is open willing to accept the "hello, webpage!" message.
             *
             * Another way of validating, is by having the app wait for the 
             * "hello, host!" message. If that response is not received within a second
             * the app host could simply reload the app.
             */

            messageSource = e.source;
            messageOrigin = e.origin;
            messageSource.postMessage("hello, host!", messageOrigin);
        }
    } else {
        // Handle messages however you like. This will simply respond to every message:
        messageSource.postMessage('Your message: ' + e.data, messageOrigin);
    }
});

这篇关于如何在Chrome App中与WebView进行通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆