跨域訪問方法介紹(5)--使用 window.postMessage 傳遞數據

postMessage 是 HTML5 XMLHttpRequest Level 2 中的 API,能夠用於窗口間消息的傳遞:頁面和其打開的新窗口的數據傳遞、頁面與嵌套的frame消息傳遞、頁面與嵌套的iframe消息傳遞。本文主要介紹經過使用 postMessage 方法來實現不一樣域下頁面間的通訊,文中所使用到的軟件版本:Chrome 90.0.4430.212。javascript

一、語法

1.一、發送消息

otherWindow.postMessage(message, targetOrigin, [transfer]);

otherWindow
其餘窗口的一個引用,好比 iframe 的 contentWindow 屬性、執行 window.open 返回的窗口對象、或者是命名過或數值索引的 window.frames。html

message
將要發送到其餘 window的數據。它將會被結構化克隆算法序列化。這意味着你能夠不受什麼限制的將數據對象安全的傳送給目標窗口而無需本身序列化。java

targetOrigin
經過窗口的 origin 屬性來指定哪些窗口能接收到消息事件,其值能夠是字符串 "*"(表示無限制)或者一個URI。在發送消息的時候,若是目標窗口的協議、主機地址或端口這三者的任意一項不匹配 targetOrigin 提供的值,那麼消息就不會被髮送;只有三者徹底匹配,消息纔會被髮送。這個機制用來控制消息能夠發送到哪些窗口;例如,當用 postMessage 傳送密碼時,這個參數就顯得尤其重要,必須保證它的值與這條包含密碼的信息的預期接受者的 origin 屬性徹底一致,來防止密碼被惡意的第三方截獲。若是你明確的知道消息應該發送到哪一個窗口,那麼請始終提供一個有確切值的 targetOrigin,而不是*。不提供確切的目標將致使數據泄露到任何對數據感興趣的惡意站點。web

transfer(可選)
是一串和 message 同時傳遞的 Transferable 對象。這些對象的全部權將被轉移給消息的接收方,而發送一方將再也不保有全部權。算法

1.二、接受消息

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event) {
  if (event.origin !== "http://example.org:8080") {
    return;
  }

  //...
}

event 的屬性有:tomcat

data
從其餘 window 中傳遞過來的對象。安全

origin
調用 postMessage 時消息發送方窗口的 origin。app

source
對發送消息的窗口對象的引用; 您可使用此來在具備不一樣 origin 的兩個窗口之間創建雙向通訊。webapp

二、樣例

在 http://a.com:8080/a.html 打開 http://b.com:8080/b.html,而後在 a.html 給 b.html 頁面發送消息,b.html 回消息給 a.html。post

2.一、模擬域名訪問

在 C:\Windows\System32\drivers\etc\hosts 文件中增長:

127.0.0.1 a.com
127.0.0.1 b.com

2.二、a.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>父頁面</title>
<script type="text/javascript">
    var child;
    function openChild() {
        child = window.open("http://b.com:8080/b.html");
    }
    function sendMessage() {
      child.postMessage("該消息來自父頁面", "http://b.com:8080");
    }
    
    function receiveMessage(event) {
        if (event.origin !== "http://b.com:8080") {
            alert('來源不可信:' + event.origin);
            return;
        }
        alert(event.data);
    }
    
    window.addEventListener("message", receiveMessage, false);
</script>
</head>
<body>
    <button onclick="openChild()">打開子頁面</button>
    <button onclick="sendMessage()">發送消息到子頁面</button>
</body>

</html>

2.三、b.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>子頁面</title>
<script type="text/javascript">
    function receiveMessage(event) {
        if (event.origin !== "http://a.com:8080") {
            alert('來源不可信:' + event.origin);
            return;
        }
        alert(event.data);
        
        event.source.postMessage("該消息來自子頁面", event.origin);
    }
    
    window.addEventListener("message", receiveMessage, false);
</script>
</head>
<body>
    子頁面
</body>

</html>

2.四、部署訪問

把 a.html 和 b.html 放到 tomcat 的 webapps\ROOT 下,訪問地址爲:http://a.com:8080/a.html。

相關文章
相關標籤/搜索