天天看點

#yyds幹貨盤點#iframe通信

如果兩個 URL 具有相同的協定,域,和端口,則稱它們是​

​同源​

​的。

以下幾個URL是同源的:

  • site.com
  • site.com/
  • site.com/a/index.htm…

以下是不同源的:

  • https://site.com
  • http://bbs.site.com
  • site.com:8080
  • http://site.org

同源政策規定:

  • 如果我們有對另一個視窗的引用(window.open || iframe),并且該視窗是同源的,那麼我們就具有對該視窗的全部通路權限。
  • 如果不是同源的,我們就不能通路視窗中的内容:變量,文檔,任何東西。唯一例外是location:我們可以修改它,使用它進行重定向。但是我們無法讀取 location 。是以,我們無法看到使用者目前所處的位置,也就不會洩露任何資訊。

iframe的通信離不開postMessage,下面聊一聊postMessage onmessage。

postMessage onmessage

想要發送消息的視窗需要調用接收視窗的 ​

​postMessage​

​​ 方法。換句話說,如果我們想把消息發送給 ​

​win​

​​,我們應該調用 ​

​win.postMessage(data, targetOrigin)​

​。

參數

​data​

要發送的資料。可以是任何對象,資料會被通過使用“結構化序列化算法(structured serialization algorithm)”進行克隆。IE 浏覽器隻支援字元串,是以我們需要對複雜的對象調用 ​

​JSON.stringify​

​ 方法進行處理,以支援該浏覽器。

​targetOrigin​

指定目标視窗的源,以便隻有來自給定的源的視窗才能獲得該消息。

// <iframe src="http://127.0.0.1:8080/2.html" name="example" />  
 
 let win = window.frames.example;    
 win.postMessage("message", "http://127.0.0.1:8080");       

為了接收消息,目标視窗應該在 ​

​message​

​​ 事件上有一個處理程式。當 ​

​postMessage​

​​ 被調用時觸發該事件(并且 ​

​targetOrigin​

​ 檢查成功)。

event 對象具有特殊屬性:

  • ​data​

    ​ 從

    postMessage

    傳遞來的資料。
  • ​origin​

    ​ 發送方的源,例如

    http://javascript.info

  • ​source​

    ​ 對發送方視窗的引用。如果我們想,我們可以立即

    source.postMessage(...)

    回去。
window.addEventListener("message", function(event) {
   console.log(event)
   if (event.origin != 'http://http://127.0.0.1:8080') {
     // 來自未知的源的内容,我們忽略它
     return;
   }
 
   if (window == event.source) {
     // chrome 下, 頁面初次加載後會觸發一次 message 事件, event.source 是 window 對象
     // 此時 event.source.postMessage 會形成死循環
     // 是以,要跳過第一次的初始化觸發的情況
     return
   }
     
   console.log( "received: " + event.data );
 
   // 可以使用 event.source.postMessage(...) 向回發送消息
   event.source.postMessage('i am 2.html')
 }, source);