APP如何与H5通信?

postMessage

postMessage可以安全地实现跨源通信。从广义上讲,一个窗口可以获得对另一个窗口的引用(比如 targetWindow = window.opener),然后在窗口上调用 targetWindow.postMessage() 方法分发一个 MessageEvent[1] 消息。

具体用法参考potsMessage-MDN[2]

下面进行实践。

两个页面通信

实现效果:A页面打开B页面,之后进行相互通信。

代码实现

A:

<input type="text" id="ipt" />
<button id="btn">点击操作页面</button>
<script>
    btn.onclick = function(){
         const w2 = window.open('http://127.0.0.1:5500/src/utils/index2.html');

        w2.onload = function () {
            w2.postMessage('页面一 发送====> 页面二', "http://127.0.0.1:5500")
        }
    }

    window.addEventListener('message',function(e){
        console.log(e.data);
        ipt.value = e.data;
    })

</script>

B:

<h2 id="h2">标题二</h2>
<button id="btn">点击</button>

<script>
    const parentWindow = window.opener;
    /* 如果是从 http://127.0.0.1:5500 中的某个页面将B页面打开,那么就能成功发送跨文档信息
     如果讲此处的URI换成"*",就意味着任何网页打开B页面,都能收到B页面传输的信息
     */
    btn.onclick = function(){
        parentWindow.postMessage(h2.innerHTML,'http://127.0.0.1:5500');
    }
    window.addEventListener('message', function (e) {
        console.log(e.data);
        ipt.value = e.data;
    })
</script>

A发送给B

c2bbdee22e984b7bf9216b7f74cc6cbb.jpeg

image.png

B发送给A

ae66f6cbefd0f427c46b06cd59e6484d.jpeg

image.png

这样就完成了两个页面的相互通信。

iframe通信

实现效果:在父页面嵌入子页面,进行父子通信。

代码实现

父:

<iframe src="http://127.0.0.1:5500/src/utils/index2.html" frameborder="1" width="100%" height="500px" id="Bframe"></iframe>

<script>
    window.onload = ()=>{
        let frame = window.frames[0];
        frame.postMessage("父====>子","http://127.0.0.1:5500")
    }
    window.addEventListener('message', function (e) {
        console.log('父接受数据',e.data);
    })
</script>

子:

<input type="text" id="ipt" />
<button id="frameBtn">iframe点击</button>

<script>
    frameBtn.onclick = function(){
        window.top.postMessage(h2.innerHTML,'http://127.0.0.1:5500');

    }
    window.addEventListener('message', function (e) {
        console.log(e.data);
        ipt.value = e.data;
    })
</script>

效果

720b3879f9e1dc7dd5d249c3803b0c78.jpeg

image.png

总结

  • window.postMessage中的window指的是你想发送跨域消息的那个窗口(你需要通信的目标窗口),而不是自身窗口的window

    • 父页面中:父页面向子页面发送跨域信息,window就是在父页面中嵌入的iframe指向的子页面的window,即:iFrame.contentWindow

    • 子页面中:子页面想父页面发送跨域信息,window就是父页面的window,在这里因为子页面是嵌入到父页面中的,对于子页面来讲,window就是top或者parent

  • 需要等到iframe中的子页面加载完成后才发送消息,否则子页面接收不到消息

  • 在监听message事件时需要判断一下消息来源origin


  1. 如果指定了origin 必须相同 如果是localhost 和 127.0.0.1 会报错

dd4a261d812acd4ebcb23f15b1469046.jpeg
image.png

app与h5通信

原生APP和h5之间可以使用jsBridge进行通信,也可以使用postMessage进行通信。

以安卓为例:

  1. 接受APP消息:

// 安卓端
webView.loadUrl("javascript:window.postMessage('Hello H5 OnClick', '*');");


// H5 监听来自App的消息
window.addEventListener('message', (event) => {
  console.log('Received message from App:', event.data);
});
  1. 发送消息到APP:

// H5发送
const message = {
    data: 'h5 send',
};
const url = `/sendMsg/${encodeURIComponent(JSON.stringify(message))}`;
window.location.href = url;


// 安卓端
@Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { 
    LogUtils.e("shouldInterceptRequest", request.getUrl().toString()); 
    return super.shouldInterceptRequest(view, request); 
}

结果如下:

a130adb9fece10fae38bc150f2e260d9.jpeg

总结


postMessage是一种安全的实现跨源通信的方式。它可以在不同的窗口之间传递消息,无论这些窗口是同源还是不同源。通过postMessage,我们可以实现以下几种通信方式:

  1. 不同窗口之间的通信

  2. 父页面与嵌入的子页面之间的通信

  3. H5与原生APP之间的通信

在使用postMessage时,需要指定消息的来源origin,以确保安全性。另外,为了确保消息的接收方能够正确接收到消息,最好在发送消息之前确保目标窗口已经加载完成。

作者:诺滚雪球

https://juejin.cn/post/7294425916549152783

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当在H5页面中使用JSBridge与APP通信时,需要先在APP端注入一个JSBridge对象,然后在H5页面中通过该对象调用APP提供的方法。下面是具体的实现步骤: 1. 在APP端注册一个JSBridge对象,并注入到WebView中。这里以Android为例,示例代码如下: ```java WebView webView = findViewById(R.id.web_view); WebViewJavascriptBridge bridge = new WebViewJavascriptBridge(webView, new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { // 处理H5页面发送过来的数据 } }); bridge.registerHandler("test", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { // 处理H5页面发送过来的test数据 } }); ``` 其中,WebViewJavascriptBridge是一个封装了WebView和JSBridge的类,BridgeHandler是一个处理JSBridge消息的接口,CallBackFunction是一个回调函数,用于将结果返回给H5页面。在这个示例中,我们注册了一个名为"test"的方法,并在其中处理从H5页面发送过来的数据。 2. 在H5页面中引入WebViewJavascriptBridge.js文件,并在页面加载完毕后初始化JSBridge对象。示例代码如下: ```javascript <script src="WebViewJavascriptBridge.js"></script> <script> // 初始化JSBridge对象 var bridge = new WebViewJavascriptBridge(function(message, responseCallback) { // 处理APP端发送过来的数据 }); // 发送数据给APP端 bridge.send('Hello from H5!'); // 调用APP端提供的方法 bridge.callHandler('test', {'data': 'Hello from H5!'}, function(response) { // 处理APP端返回的结果 }); </script> ``` 在这个示例中,我们初始化了一个JSBridge对象,并发送了一条消息给APP端。同时,我们还调用了APP端提供的名为"test"的方法,并将包含"data"字段的JSON对象作为参数传递给了APP端。当APP端处理完这个方法后,会将结果返回给H5页面,并通过回调函数处理这个结果。 通过上述步骤,就可以在H5页面中使用JSBridge与APP端进行通信了。需要注意的是,JSBridge的实现方式可能因平台和版本而异,具体实现方式需要根据实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值