Js的iframe相關問題,如何判斷當前是否在iframe中,iframe和它的父窗口如何通信


 

一、前言:

  在web中,為了豐富我們的內容,往往需要引用其它HTML文件,這時候就需要用到 iframe 標簽,本文就主要記錄一下使用iframe所需要注意的問題

 

  iframe 所使用的環境(筆者所遇到的)

  1. web代碼兼容 PC端 和 移動端,這時候就想在移動端時把頁面限制在固定的寬高范圍中,於是就使用 iframe 把 相關頁面限制在其中

  2. web引用別人的 HTML 內容,就使用iframe 來實現

 

二、遇到的問題:

1. 如何判斷當前是否在iframe中

// 1
if (self.frameElement && self.frameElement.tagName == "IFRAME") {   alert('在iframe中'); } // 2
if (window.frames.length != parent.frames.length) {   alert('在iframe中'); } // 3
if (self != top) {   alert('在iframe中'); }

 說明:

  • 三種方式都是根據當前的窗口層級進行判斷,
  • 以上是針對有 <frameset> 或者 <iframe> 的頁面,
  • self.frameElement 可以獲取到當前的 iframe 節點(如果有的話),否則為null

 解釋:window、top、parent、self 之間的聯系和區別

  • window : 當前窗口
  • top: 頂層窗口,針對有很多層的iframe
  • parent: 父級窗口,即當前窗口的上一層窗口
  • self: 當前窗口,和window、window.self  等價

 

2. iframe 和 它的父窗口如何通信

  注意有兩種情況:

  • iframe 和 父窗口 同源(即不會跨域,相同域名下),可以直接使用 節點 或 window 調用
    • iframe 獲取父窗口節點:parent.window.document.getElementById("parentNode")
    • iframe 調用父窗口方法:parent.parentFunc();
    • 父窗口獲取 iframe節點:iframeObj.contentWindow.document.getElementById("childNode")   
      • this.myFrame表示 iframe對象
      • var obj=document.getElementsByTagName("iframe")[0].contentWindow; var ifmObj=obj.document.getElementById("childNode");  
    • 父窗口調用 iframe方法:iframeObj.contentWindow.parentFunc()
      • var obj=document.getElementsByTagName("iframe")[0].contentWindow; obj.parentFunc();

         

  • iframe 和 父窗口 跨域(一般是調用別人的HTML )
    • 必須使用安全的 postMessage方式來進行通信
    • // 向父窗口傳值
      window.parent.postMessage({code: 1, msg: '向父窗口傳值'},*);
      
      // 向iframe傳值
      document.getElementsByTagName("iframe")[0].contentWindow.postMessage({code: 2, msg: '向iframe傳值'},*);
      
      // 接收傳值
      window.addEventList('message',  (e) => {
          try{
              if (e.data type e.data ==='string' ) {
              console.log(e.data);
              }
          } catch (err) {
              console.log(err)
          }
      });
      • event.source:發送消息的窗口,可以通過區分網址來接收消息
      • event.origin: 消息發向的網址,同上
      • event.data: 消息內容

說明:

otherWindow.postMessage(message,targetOrigin,[transfer]);
  • otherWindow: 其他窗口的一個引用,比如iframe的contentWindow屬性、執行window.open返回的窗口對象、或者是命名過或數值索引的window.frames;
  • message: 將要發送到其他window的數據,這個數據會自動被序列化,數據格式也不受限制,String字符串,對象(包括JSON)都可以;
  • targetOrigin: 通過窗口的origin屬性來指定哪些窗口能接收到消息事件,這個值可以是"*"(表示無限制),或者一個URI。在發送消息的時候,如果目標窗口的協議、主機地址或者端口這三個的任意一項不匹配targetOrigin提供的值,那么消息就不會被發送。如果你明確的知道消息應該發送到哪個窗口,那么請始終提供一個有確切值的targetOrigin,而不是*。不提供確切的目標將導致數據泄露到任何對數據感興趣的惡意站點。
  • transfer(可選): 是一串和message 同時傳遞的 Transferable 對象. 這些對象的所有權將被轉移給消息的接收方,而發送一方將不再保有所有權。

 

 三、最后

  具體請看MDN: window.postMessage

 

 


免責聲明!

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



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