postMessage用法详解
postMessage是一种跨文档通信机制,可以在不同源的窗口之间安全地传递信息,具有较高的可靠性和安全性,常用于实现iframe间的通信、父窗口与子窗口之间的通信以及不同源的窗口通信等。
基本用法
postMessage的基本用法是在消息发送窗口中调用postMessage方法,将要传递的信息以及接收窗口的origin(协议、主机名和端口号)作为参数传入。
window.postMessage(message, targetOrigin);
其中,message表示要传递的信息,可以是任意类型的数据,如字符串、JSON对象等;targetOrigin表示接收信息的窗口的origin,只有与该值完全匹配的窗口才会接收到传递的信息。
在接收窗口中,可以通过监听message事件来获取传递过来的信息。当接收到信息时,会创建一个event事件对象,其中包含data属性,表示传递过来的信息。
window.addEventListener('message', function(event){
var origin = event.origin; // 发送窗口的origin
var data = event.data; // 传递过来的信息
}, false);
需要注意的是,为确保安全性,必须在发送窗口和接收窗口中都进行合法性验证。在发送窗口中,应该限定接收窗口的origin。在接收窗口中,应该检查发送窗口的origin是否合法。
实际应用场景
iframe间通信
当一个页面中存在多个iframe时,可以通过postMessage实现这些iframe之间的信息传递,以便实现一些协同工作的效果,如同步滚动、共享数据等。
在发送iframe中,需要获取到接收iframe的window对象,然后使用postMessage方法进行信息传递。
var iframeWin = document.getElementById('iframe1').contentWindow;
iframeWin.postMessage('Hello World!', '*');
在接收iframe中,需要监听message事件,并通过event.source属性判断信息来源,进行合法性验证。
window.addEventListener('message', function(event){
if(event.source !== iframeWin){ // 判断信息来源是否合法
return;
}
var data = event.data;
}, false);
父窗口与子窗口之间通信
在一个页面中,可能会嵌入一个或多个iframe,这些iframe都具有它们自己的window对象。在这种情况下,父窗口可以使用postMessage方法与子窗口进行通信,子窗口也可以使用postMessage方法与父窗口进行通信。
在父窗口中,需要获取到子窗口的window对象,然后使用postMessage方法进行信息传递。
var childWin = window.frames[0]; // 获取子窗口的window对象
childWin.postMessage('Hello World!', '*');
在子窗口中,需要监听message事件,并通过event.source属性判断信息来源,进行合法性验证。
window.addEventListener('message', function(event){
if(event.source !== window.parent){ // 判断信息来源是否合法
return;
}
var data = event.data;
}, false);
不同源窗口通信
在同一窗口中,无论是否使用postMessage方法传递信息都不会遇到跨域的问题。但对于不同源的窗口之间的通信,必须使用postMessage方法传递信息。
在发送窗口中,需要指定接收窗口的origin,如果该origin与目标窗口的origin不同,则无法传递信息。
window.postMessage('Hello World!', 'http://www.example.com');
在接收窗口中,需要检查发送窗口的origin是否合法,如果不合法则不接收信息。
window.addEventListener('message', function(event){
if(event.origin !== 'http://www.example.com'){ // 判断发送窗口的origin是否合法
return;
}
var data = event.data;
}, false);
总结
postMessage是一种跨文档通信机制,可以安全地在不同源的窗口之间传递信息,具有较高的可靠性和安全性。它可以用于实现iframe间的通信、父窗口与子窗口之间的通信以及不同源窗口之间通信等场景。
在使用postMessage时,必须在发送窗口和接收窗口都进行合法性验证,以确保通信的安全可靠。
需要注意的是,虽然postMessage具有较高的安全性,但如果使用不当也可能会导致安全问题。因此,在使用postMessage时需要仔细考虑安全问题,避免出现不安全的情况。