问题:
1. 如何进行消息通信(父发给子,子接收父的消息,也可父直接调用子的方法; 子发给父,父接收子的消息;)
2. 如何找到指定的子或者父window(如果iframe层级过多),又如何在发送消息时不影响其他的message监听
一、iframe的使用
<iframe style={{border:0,"100%",height:630,}} src={src} />
1. 如何进行消息通信(父发给子,子接收父的消息; 子发给父,父接收子的消息)
// 父监听子消息: window.addEventListener("message", () => this.listenFunc())
// 子发给父消息: 可通过window的属性找到对应的父(这里的parent表示直接上一级的父) parent.postMessage(data, "*")
// 父调用子的方法: this.iframe.contentWindow.iframe的属性方法 // 或 document.getElementById("myIframe").contentWindow.iframe的属性方法
2. 如何找到指定的子或者父window(如果iframe层级过多),又如何在发送消息时不影响其他的message监听
while(true) { // 判断,找到要找的父window,可以通过在父的window上绑定属性来实现 if(currentWindow.isParent = true) { currentWindow.postMessage(data, "*") } if(currentWindow == window.top) { break; // 防止死循环 } else { currentWindow = currentWindwo.parent; } }
3. origin是否有用
event.origin 可以获取当前消息的来源路径,通过判断当前iframe的url,判断是否是指定页面的消息来源
二、React Native的WebView和子内容的通信
// RN的WebView <WebView ref={ref => this.webview = ref} source={{uri: ...}} javaScriptEnabled={true} onMessage={this.handleMassage} allowFileAccess={true} onLoadStart={} onLoadEnd={} />
1. 监听接收web(子)发送的消息
// 接收web发送的消息 handleMessage(event) { const data = JSON.parse(event.nativeEvent.data); const code = data.code; const msg = data.msg; switch(code) { case 0: console.log(msg); break; } }
2. web(子)发消息给react native
// web发消息给react native const data = {code: code, msg: msg}; window.ReactNativeWebView.postMessage(JSON.stringify(data));
3. React Native(父)发送消息给web(子)
// 发送消息给web sendMessageToWebView(code, msg) { const data = {code: code, msg: msg}; if(this.webview) { this.webview.postMessage(JSON.stringify(data)); } else { console.log("no webview ref") } }
4. web(子)对React Native(父)消息的监听
// web监听react native的postMessage消息,必须有document, 否则监听不到消息 window.document.addEventListener("message", this.onMessageListener.bind(this)); onMessageListener(event) { const data = JSON.parse(event.data); const code = data.code; const msg = data.msg; switch(code) { case ... } }
三、 android的webview和包含内容的通信(仅做简单介绍)
agentWeb 相对于webview的使用
android 中可以定义当前的window下的名称,
web可以使用 类似window.WebAppInterface.onPostMessage(JSON.stringify(data))来发消息,WebAppInterface需要在Android中定义
综上:
web的iframe之间,web和RN的webview之间,web和android之间的通信,都是使用message进行监听的,需要关注消息来源,否则如果有多个同类型不同类型的消息,很容易引起监听的冲突混淆
针对消息的发送,三种类型各不相同,但是多个同类型之间需要做好区分,否则依然有冲突混淆的问题