HTML5 postMessage传输与POST跨域通讯

HTML5 postMessage传输与POST跨域通讯
HTML5 的 postMessage 方法可实现不同窗体间互相通信。

HTML5 的 postMessage 方法可实现不同窗体间互相通信。

postMessage 支持实现跨文档消息传输(Cross Document Messaging),并且可跨域传输信息。Internet Explorer 8, Firefox 3, Opera 9, Chrome 3和 Safari 4 以上版本浏览器都已支持 postMessage。

postMessage 功能简介

父(主页面)窗体向子窗体发送消息

首先要获取传送的窗体对象(iframe),并向对象发送信息

1
2
var iframeWin = document.getElementsByTagName('iframe')[0].contentWindow;
iframeWin.postMessage('hello world!', "*");

postMessage方法包含了两个参数,第一个为发送的内容,类型为:string。第二个接受窗体的URL限制,这里使用 “*”,表示所有域都可以接收传送的内容。

子窗口监听发送来的消息

1
2
3
4
5
6
7
8
9
10
window.addEventListener('message', onMessage, false);
var onMessage = function(e){
console.log(e.data);
if(e.origin !="http://moweide.gitcafe.io"){
return false;
}
// 消息处理...
}
};

通过使用e.data去获取接收的到信息,一般出于安全考虑,我们会对e.orrgin的源进行检测,如果不是预设的消息来源,应该拒绝处理。

跨域

同源跨域可通过修改 window.domain 方式欺骗解决。

非同源跨域可使用 flash 控件或远程加载script文件的 jsonp 方式。

现在 postMessage 则可简单完成该需求,重要的是,它可以实现 jsonp 无法完成的跨域 POST 请求。

父窗体创建跨域iframe并发送信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>跨域POST消息发送</title>
<script type="text/JavaScript">
function sendPost(){
var iframeWin = document.getElementById("otherPage").contentWindow;
iframeWin.postMessage( document.getElementById("message").value, "http://moweide.gitcafe.io");
}
window.addEventListener("message", function( event ) {
console.log(event, event.data);
}, false);
</script>
</head>
<body>
<textarea id="message"></textarea>
<input type="button" value="发送" onclick="sendPost()">
<iframe src="http://moweide.gitcafe.io/other-domain.html" id="otherPage" style="display:none"></iframe>
</body>
</html>

子窗体接收信息并处理(如发起XMLHttpRequest请求)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>POST Handler</title>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/JavaScript">
window.addEventListener("message", function( event ) {
// 把父窗口发送过来的数据向服务器发送post请求
var data = event.data;
$.ajax({
type: 'POST',
data: "info=" + data,
dataType: "json"
}).done(function(res){
//可以向父窗体返回结果
window.parent.postMessage(res, "*");
}).fail(function(res){
window.parent.postMessage(res, "*");
});
}, false );
</script>
</head>
<body>
</body>
</html>

postMessage 总结

postMessage 解决了客户端不同窗体间的消息传递问题,特别是跨域消息发送,可解决跨域 POST 请求问题。

另外,解决客户端与服务器的双向实时通信,可参考 HTML5 的 webSocket API.