您的位置:首页 > Web前端 > HTML5

HTML5 postMessage 消息传输与 POST 跨域通信

2015-05-06 15:52 357 查看
HTML5 的 postMessage 方法可实现不同窗体间互相通信。

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


1. postMessage 功能简介

postMessage 主要包含两个 API:

1).消息监听:onmessage

2).消息发送:postMessage

使用步骤也很简单:


1.1.监听发送过来的消息

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

e.data 即接收到的信息。

由于该监听可接收任意发送过来的消息,故一般应对 e.origin 来源进行检测,如果不是预设的消息来源,应予以拒绝处理。


1.2.向其他窗体发送消息

首先获取要传送消息的窗体对象(如iframe),然后向该对象发送信息

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

postMessage 包含两个参数,第一个参数为发送的消息内容,为字符串类型。第二个为来源域限制。即限制接收窗体的 URL。

进行跨文档消息发送,首先要获取传送对象窗体。所以 postMessage 常用在从当前页创建/打开新窗体或新的 worker 线程中,实现双方通信。请与志文工作室一起来看如下使用示例。


2. worker 多线程

消息接收处理页面:

01
<!DOCTYPE
html>
02
<
html
>
03
<
head
>
04
<
meta
charset
=
"utf-8"
>
05
<
meta
http-equiv
=
"X-UA-Compatible"
content
=
"IE=edge"
>
06
<
title
>Test
Web worker</
title
>
07
<
script
type
=
"text/JavaScript"
>
08
function
init(){
09
var
worker = new Worker('compute.js');
10
11
//event
参数中有 data 属性,就是子线程中返回的结果数据
12
worker.onmessage=
function (event) {
13
//
把子线程返回的结果添加到 div 上
14
document.getElementById("result").innerHTML
+= event.data+"<
br
/>";
15
};
16
}
17
</
script
>
18
</
head
>
19
<
body
onload
=
"init()"
>
20
<
div
id
=
"result"
></
div
>
21
</
body
>
22
</
html
>
消息发送 compute.js

compute.js 中调用 postMessage 方法发送计算结果

01
var
i=0;
02
03
function
timedCount(){
04
for
(
var
j=0,sum=0;j<100;j++){
05
for
(
var
i=0;i<100000000;i++){
06
sum+=i;
07
}
08
}
09
//
调用 postMessage 向主线程发送消息
10
postMessage(sum);
11
}
12
13
postMessage(
"Before
computing,"
+
new
Date());
14
timedCount();
15
postMessage(
"After
computing,"
+
new
Date());


3. 跨域

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

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

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


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

01
<!DOCTYPE
html>
02
<
html
>
03
<
head
>
04
<
meta
charset
=
"utf-8"
>
05
<
meta
http-equiv
=
"X-UA-Compatible"
content
=
"IE=edge"
>
06
<
title
>跨域POST消息发送</
title
>
07
<
script
type
=
"text/JavaScript"
>
08
function
sendPost(){
09
var
iframeWin = document.getElementById("otherPage").contentWindow;
10
iframeWin.postMessage(
document.getElementById("message").value,"http://w.lzw.me:81");
11
}
12
13
window.addEventListener("message",
function( event ) {
14
console.log(event,
event.data);
15
},
false);
16
</
script
>
17
</
head
>
18
<
body
>
19
<
textarea
id
=
"message"
></
textarea
>
20
<
input
type
=
"button"
value
=
"发送"
onclick
=
"sendPost()"
>
21
<
iframe
src
=
"http://w.lzw.me:81/other-domain.html"
id
=
"otherPage"
style
=
"display:none"
></
iframe
>
22
</
body
>
23
</
html
>


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

other-domain.html

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


4. postMessage 总结

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

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


5. 相关参考

http://www.ibm.com/developerworks/cn/web/1301_jiangjj_html5message/

原文链接: http://lzw.me/a/html5-postmessage-post-cross-domain.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HTML5 postMessage