postMessage是干什么的呢?
我們都知道解決跨域有多種方式,什么jsonp啦、cors啦、nginx反向代理啦等等,postMessage也是解決跨域的一種方式。那它通常用在什么地方呢?一般是頁(yè)面和嵌入的iframe或者一個(gè)頁(yè)面和它生成的彈出窗口之間。
postMessage如何使用呢?
知道了postMessage是干什么的,那我們?cè)撊绾问褂盟兀壳襾?lái)看一下它的語(yǔ)法:
發(fā)送消息:
otherWindow.postMessage(message, targetOrigin, [transfer]);
- otherWindow
其他窗口的引用,向誰(shuí)發(fā)消息,就獲取誰(shuí)的窗口引用。`始終是你要通信的目標(biāo)頁(yè)面的window`
- targetOrigin
通過(guò)設(shè)置origin屬性來(lái)指定哪些窗口能接收到消息事件??梢允亲址?*",表示沒(méi)有限制;
也可以是一個(gè)URI,只有目標(biāo)窗口的協(xié)議、主機(jī)地址、端口號(hào)跟targetOrigin完全匹配時(shí),才能接收到消息。
不提供確切的targetOrigin將導(dǎo)致數(shù)據(jù)泄漏到任何對(duì)數(shù)據(jù)感興趣的惡意站點(diǎn)。
- transfer(可選)
是一串和message 同時(shí)傳遞的 [Transferable](https://developer.mozilla.org/zh-CN/docs/Web/API/Transferable) 對(duì)象. 這些對(duì)象的所有權(quán)將被轉(zhuǎn)移給消息的接收方,而發(fā)送一方將不再保有所有權(quán)。
接收消息:
window.addEventListener("message", receiveMessage, false);
receiveMessage的屬性有:
- data
從其他window中傳遞過(guò)來(lái)的對(duì)象
- origin
調(diào)用postMessage時(shí)消息發(fā)送方窗口的origin。注意,這個(gè)origin不能保證是該窗口的當(dāng)前或未來(lái)origin,因?yàn)閜ostMessage被調(diào)用后可能被導(dǎo)航到不同的位置
- source
對(duì)發(fā)送消息的窗口對(duì)象的引用
來(lái)個(gè)小栗子實(shí)戰(zhàn)一下吧
光看還是有點(diǎn)小疑惑呀,還是跑個(gè)栗子更直觀~
// parent.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>父頁(yè)面收發(fā)消息</title>
<script type="text/JavaScript">
// sendIframe 通過(guò)postMessage實(shí)現(xiàn)跨域通信將表單信息發(fā)送到iframe上,
function sendIframe() {
// 獲取id為iframePage的iframe窗口對(duì)象
var iframeWin = document.querySelector("#iframePage").contentWindow;
// 向該窗口發(fā)送消息
iframeWin.postMessage(document.querySelector("#message").value, 'http://example.iframe.com');
}
// 監(jiān)聽(tīng)iframe的消息事件
window.addEventListener("message", function(event) {
// 可以利用origin屬性做驗(yàn)證
if (event.origin !== 'http://example.iframe.com') {
return;
}
console.log('接收子窗口數(shù)據(jù)', event);
}, false);
</script>
</head>
<body>
<textarea id="message"></textarea>
<input type="button" value="發(fā)送" onclick="sendIframe()">
<iframe src="http://example.iframe.com/child.html" id="iframePage"></iframe>
</body>
</html>
// child.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>子頁(yè)面收發(fā)消息</title>
<script type="text/JavaScript">
// 監(jiān)聽(tīng)父窗口發(fā)送過(guò)來(lái)的數(shù)據(jù)
window.addEventListener("message", function(event) {
// 可以利用origin屬性做驗(yàn)證
if (event.origin !== 'http://example.com') {
return;
}
console.log('接收父窗口數(shù)據(jù)', event);
}, false);
function sendParent() {
// 向父窗口發(fā)送消息
window.parent.postMessage(document.querySelector("#ifameMessage").value, 'http://example.com');
}
</script>
</head>
<body>
<textarea id="ifameMessage"></textarea>
<input type="button" value="發(fā)送" onclick="sendParent()">
</body>
</html>
有什么不對(duì)的地方,還請(qǐng)指正哦~