(轉)使用 iframe + postMessage 實現跨域通訊

    在實際項目開發中可能會碰到在 a.com 頁面中嵌套 b.com 頁面,這時第一反應是使用 iframe,可是產品又提出在 a.com 中操做,b.com 中進行顯示,或者相反。

一、postMessage

    postMessage方法容許來自不一樣源的腳本採用異步方式進行有限的通訊,能夠實現跨文本檔、多窗口、跨域消息傳遞。 語法:html

otherWindow.postMessage(message, targetOrigin, [transfer]);複製代碼
  •     otherWindow:其餘窗口的引用,如 iframe的contentWindow、執行window.open返回的窗口對象、或者是命名過或數值索引的window.frames。
  •     message:將要發送到其餘window的數據。 
  •     targetOrigin:指定那些窗口能接收到消息事件,其值能夠是字符串 「*」 表示無限制,或者是一個URI。 
  •     transfer:是一串和message同時傳遞的Transferable對象,這些對象的全部權將被轉移給消息的接收方,而發送方將再也不保留全部權。 

    postMessage方法被調用時,會在全部頁面腳本執行完畢以後像目標窗口派發一個 MessageEvent 消息,該MessageEvent消息有四個屬性須要注意: type:表示該message的類型 data:爲 postMessage 的第一個參數 origin:表示調用postMessage方法窗口的源 source:記錄調用postMessage方法的窗口對象。
跨域

二、搭建框架

main.htmlbash

<!DOCTYPE html> 
<html>
<head>
<meta charset="utf-8">
<title>iframe+postMessage 跨域通訊 主頁面</title>
</head>
<body>
    <h1>主頁面</h1>
    <iframe id="child" src="http://b.com/iframepage.html"></iframe>
    <div>
        <h2>主頁面接收消息區域</h2>
        <span id="message"></span>
    </div>
</body> 
</html>複製代碼

iframepage.html
框架

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>iframe+postMessage跨域通訊 子頁面</title>
</head>
<body>
    <h2>子頁面</h2>
    <div>
        <h3>接收消息區域</h3>
        <span id="message"></span>
    </div>
</body>
</html>複製代碼

二、父向子發送消息

main.html異步

<script>
    window.onload = function(){
        document.getElementById('child')
         .contentWindow.postMessage("主頁面消息", 
                "http://b.com/iframepage.html")
    }
</script>複製代碼

注意:必定是頁面加載完成後在發送消息,不然會由於 iframe 未加載完成報錯。
post

Failed to execute ‘postMessage’ on ‘DOMWindow’複製代碼

子頁面接收消息:
iframepage.html
ui

<script>
    window.addEventListener('message',function(event){
        console.log(event);
        document.getElementById('message').innerHTML = "收到" 
            + event.origin + "消息:" + event.data;
    }, false);
</script>複製代碼

此時可看到頁面中,iframe的子頁面中打印了
spa

收到http://a.com消息:主頁面消息複製代碼


以及控制檯打印了MessageEvent對象。
.net


三、子向父發送消息

子頁收到消息後回覆父頁面
iframepage.htmlcode

<script>
    window.addEventListener('message',function(event){
        console.log(event);
        document.getElementById('message').innerHTML = "收到" 
            + event.origin + "消息:" + event.data;
        top.postMessage("子頁面消息收到", 'http://a.com/main.html')
    }, false);
</script>複製代碼

父頁面收到消息並顯示:

window.addEventListener('message', function(event){
    document.getElementById('message').innerHTML = "收到" 
        + event.origin + "消息:" + event.data;
}, false);複製代碼


四、完整代碼

main.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>iframe+postMessage 跨域通訊 主頁面</title>
</head>
<body>
    <h1>主頁面</h1>
    <iframe id="child" src="http://b.com/iframepage.html"></iframe>
    <div>
        <h2>主頁面接收消息區域</h2>
        <span id="message"></span>
    </div>
</body> 
<script>
    window.onload = function(){
        document.getElementById('child')
         .contentWindow.postMessage("主頁面消息", 
            "http://b.com/iframepage.html")
    }
    window.addEventListener('message', function(event){
        document.getElementById('message').innerHTML = "收到"
         + event.origin + "消息:" + event.data;
    }, false);
</script>
</html>複製代碼

iframepage.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>iframe+postMessage跨域通訊 子頁面</title>
</head>
<body>
    <h2>子頁面</h2>
    <div>
        <h3>接收消息區域</h3>
        <span id="message"></span>
    </div>
</body>
<script>
    window.addEventListener('message',function(event){
        if(window.parent !== event.source){return}
        console.log(event);
        document.getElementById('message').innerHTML = "收到" 
            + event.origin + "消息:" + event.data;
        top.postMessage("子頁面消息收到", 'http://a.com/main.html')
    }, false);
</script>
</html>複製代碼

--------------------- 

 做者:tang_yi_ 

 來源:CSDN 

 原文:https://blog.csdn.net/tang_yi_/article/details/79401280 

相關文章
相關標籤/搜索