實現兩個視窗通訊方法之postMessage
兩個視窗的通訊問題應該是一個比較常見的問題了,通訊可以通過很多種方式,如下:
localStorage
postMessage
websocket
今天博主先來一篇postMessage乾貨,後期還會給出websocket的實現程式碼。
首先來看一下基本的語法
otherWindow.postMessage(message, targetOrigin, [transfer]);
-
otherWindow
其他視窗的一個引用,比如iframe的contentWindow屬性、執行window.open返回的視窗物件、或者是命名過或數值索引的window.frames。
-
message
將要傳送到其他 window的資料。它將會被結構化克隆演算法序列化。這意味著你可以不受什麼限制的將資料物件安全的傳送給目標視窗而無需自己序列化。
-
targetOrigin
通過視窗的origin屬性來指定哪些視窗能接收到訊息事件,其值可以是字串”“(表示無限制)或者一個URI。在傳送訊息的時候,如果目標視窗的協議、主機地址或埠這三者的任意一項不匹配targetOrigin提供的值,那麼訊息就不會被髮送;只有三者完全匹配,訊息才會被髮送。這個機制用來控制訊息可以傳送到哪些視窗;例如,當用postMessage傳送密碼時,這個引數就顯得尤為重要,必須保證它的值與這條包含密碼的資訊的預期接受者的orign屬性完全一致,來防止密碼被惡意的第三方截獲。如果你明確的知道訊息應該傳送到哪個視窗,那麼請始終提供一個有確切值的targetOrigin,而不是。不提供確切的目標將導致資料洩露到任何對資料感興趣的惡意站點。
-
transfer
是一串和message 同時傳遞的 Transferable 物件. 這些物件的所有權將被轉移給訊息的接收方,而傳送一方將不再保有所有權。
message的屬性:
-
data
從其他 window 中傳遞過來的物件。
-
origin
呼叫 postMessage 時訊息傳送方視窗的 origin . 這個字串由 協議、“://“、域名、“ : 埠號”拼接而成。例如 “https://example.org (implying port 443)”、“http://example.net (implying port 80)”、“http://example.com:8080”。請注意,這個origin不能保證是該視窗的當前或未來origin,因為postMessage被呼叫後可能被導航到不同的位置。
-
source
對傳送訊息的視窗物件的引用; 您可以使用此來在具有不同origin的兩個視窗之間建立雙向通訊。
安全方面
如果不接受message,那麼就不要新增message事件的監聽器
如果您確實希望從其他網站接收message,請始終使用origin和source屬性驗證發件人的身份。 任何視窗(包括例如http://evil.example.com)都可以向任何其他視窗傳送訊息,並且您不能保證未知發件人不會傳送惡意訊息。 但是,驗證身份後,您仍然應該始終驗證接收到的訊息的語法。 否則,您信任只傳送受信任郵件的網站中的安全漏洞可能會在您的網站中開啟跨網站指令碼漏洞。
當您使用postMessage將資料傳送到其他視窗時,始終指定精確的目標origin,而不是*。 惡意網站可以在您不知情的情況下更改視窗的位置,因此它可以攔截使用postMessage傳送的資料。
完整示例如下:
//a.com/index.html
<iframe src="b.com/index.html" id="ifr">
</iframe>
<script>
window.onload = function(){
var iframe = document.getElementById('ifr');
var targetOrigin = 'http://b.com'; // 若寫成'http://b.com/c/proxy.html'效果一樣
// 若寫成'http://c.com'就不會執行postMessage了
iframe.contentWindow.postMessage('data to send',targetOrigin);
}
</script>
// b.com/index.html
<script type="text/javascript">
window.addEventListener('message',function(event){
// 通過origin屬性判斷訊息來源地址
if(event.origin == 'http://a.com'){
console.log(event.data);
console.log(event.source);
}
},false);
</script>
相關文章
- 兩個視窗如何實現通訊
- excel視窗獨立開啟不重疊 兩個excel檔案怎麼實現兩個視窗顯示Excel
- MQ實現兩個應用系統之間的通訊-----實際操作(二)MQ
- 實現多個標籤頁之間通訊的幾種方法
- 8┃音視訊直播系統之 WebRTC 信令系統實現以及通訊核心並實現視訊通話Web
- 自己實現一個滑動視窗
- WebRTC + WebSocket 實現視訊通話Web
- 附例項!實現iframe父窗體與子窗體的通訊
- 【Spring AOP】暴力打通兩個切面之間的通訊Spring
- “兩行”程式碼,幫你快速實現FaceTime的新多人視訊通話效果
- 兩個Arduino 與兩個MCP2515 CAN模組通訊實現(用到ec11編碼器)UI
- 瀏覽器跨 Tab 視窗通訊原理及應用實踐瀏覽器
- 如何基於 Flutter 快速實現一個視訊通話應用Flutter
- 實現不同程式之間的通訊
- 微服務通訊之ribbon實現原理微服務
- java鍵盤監聽之視窗監聽的實現Java
- RabbitMQ實現延時訊息的兩種方法MQ
- win10 如何快速切換兩個視窗 win10怎麼切視窗Win10
- 捷視飛通視訊通訊系統實現菸草行業打假打私視覺化指揮行業視覺化
- offer通過--7兩個棧實現佇列-2佇列
- offer通過--8兩個棧實現佇列-2佇列
- PyQT5之訊號關閉視窗QT
- Hystrix指標視窗實現原理指標
- C# winForm 視窗跳轉後關閉上一個視窗的方法C#ORM
- 【網路安全】PostMessage:分析JS實現XSSJS
- Android端實現多人音視訊聊天應用(二):多人視訊通話Android
- 兩個 Node.js 程式如何在h5直播原始碼中實現通訊?Node.jsH5原始碼
- 兩個專案用訊息佇列通訊佇列
- 一個簡單的時間視窗設計與實現
- 基於 WebRTC 和 WebVR 實現 VR 視訊通話WebVR
- 技術分享| 小程式實現音視訊通話
- JAVA 兩個類同時實現同一個介面的方法Java
- 網路通訊2:TCP通訊實現TCP
- python實現兩臺不同主機之間進行通訊(客戶端和服務端)——SocketPython客戶端服務端
- 短視訊app原始碼,提示以按鈕彈窗的形式實現APP原始碼
- 面試題之【用兩個棧實現佇列】面試題佇列
- 基於 Electron 做視訊會議的兩種實現方式
- 微信小程式之animation底部彈窗動畫(兩種方法)微信小程式動畫