iframe的使用和 contentWindow、parent以及postMessage通信方式


 

問題:

1. 如何進行消息通信(父發給子,子接收父的消息,也可父直接調用子的方法; 子發給父,父接收子的消息;)

2. 如何找到指定的子或者父window(如果iframe層級過多),又如何在發送消息時不影響其他的message監聽

 

 

一、iframe的使用

<iframe 
style={{border:0,width:"100%",height:630,}} 
src={src}
/>

 

1. 如何進行消息通信(父發給子,子接收父的消息; 子發給父,父接收子的消息)

方法一: 直接通過獲取父或者子的window來操作 (限制: 必須同域)

// 父調用子的方法:
 this.iframe.contentWindow.iframe的屬性方法
//
document.getElementById("myIframe").contentWindow.iframe的屬性方法

// 子調用父的方法:通過parent直接獲取父的window
parent.document...

 

方法二:通過postMessage進行通信(限制: 需要父子約定)

// 父監聽子消息:
window.addEventListener("message", () => this.listenFunc());

// 子發給父消息: 可通過window的屬性找到對應的父(這里的parent表示直接上一級的父)
parent.postMessage(data, "*");  


// 父給子發消息
document.getElementById("iframe").contentWindow.postMessage(JSON.stringify(data), "*")

// 子監聽父的消息
window.addEventListener("message", () => this.listenFunc());

 

 

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進行監聽的,需要關注消息來源,否則如果有多個同類型不同類型的消息,很容易引起監聽的沖突混淆

針對消息的發送,三種類型各不相同,但是多個同類型之間需要做好區分,否則依然有沖突混淆的問題

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM