一、问题
平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经常会遇到的问题
1.页面和其打开的新窗口的数据传递
2.多窗口之间消息传递
3.页面与嵌套的iframe消息传递
4.上面三个问题的跨域数据传递
二、postMessage()介绍
这些问题都有一些解决办法,但html5引入的message的API可以更方便、有效、安全的解决这些难题。postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
三、postMessage(data,origin)方法接受两个参数
1.data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。
2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以建参数设置为"*",这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
3.postMessage写入需要传递消息的一方
4.接收方需要编写监听事件获取信息:window.addEventListener("message",function(e){});
四、postMessage()实例
1.编写父窗口代码,parent.jsp
<body>
<div style="margin-bottom:15px;"><span>Iframe Url : </span> <input style="width:400px" type="text" id="iframe_url" value="http://localhost:8080/postMessage/iframe"/></div>
<div style="margin-bottom:15px;"><button id="load_form" type="button">Load Iframe</button></div>
<div style="margin-bottom:15px;"><span>Message : </span> <input style="width:400px" type="text" id="message"/></div>
<div style="margin-bottom:15px;"><button id="POST_Message">POST Message</button></div>
<div style="margin-bottom:15px;"><span>Receive Message : </span><label id='message_label'></label></div>
<iframe src="" id='form' style="width:100%;height:400px;"><iframe></iframe></iframe>
</body>
</html>
<script>
setTimeout(function(){
document.getElementById("load_form").onclick=function(){
var url=document.getElementById("iframe_url").value;
document.getElementById("form").setAttribute("src",url);
};
document.getElementById("POST_Message").onclick=function(){
var message=document.getElementById("message").value;
var url=document.getElementById("form").getAttribute("src");
window.frames[0].postMessage(message,url);//父窗口向子窗口发送消息,0表示第一个子窗口
};
window.addEventListener("message",function(e){
document.getElementById("message_label").innerHTML=JSON.stringify(e.data);
});
});
</script>
2.编写子窗口,iframe.jsp
<body>
<div style="margin-bottom:15px;"><span>Receive Message : </span><label id='message_label'></label></div>
<div style="margin-bottom:15px;"><button id='btn1'>Pending IRR</button> <button id='btn2'>Completed - Pending IRR</button> <button id='btn3'>Completed</button></div>
</body>
</html>
<script>
Date.prototype.format = function(fmt)
{ //author: meizz
var o = {
"M+" : this.getMonth()+1,
"d+" : this.getDate(),
"h+" : this.getHours(),
"m+" : this.getMinutes(),
"s+" : this.getSeconds(),
"q+" : Math.floor((this.getMonth()+3)/3),
"S" : this.getMilliseconds()
};
if(/(y+)/.test(fmt))
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)
if(new RegExp("("+ k +")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
return fmt;
}
window.addEventListener("message",function(e){
document.getElementById("message_label").innerHTML=e.data;//接收父窗口发送的消息
});
var json= {"PTCC_ID_1":"1234","PTCC_Accept_DT_1":"DD-MMM-YY HH:MI:SS","STATUS_1":"Completed","PTCC_ID_2":"1235","PTCC_Accept_DT_2":"DD-MMM-YY HH:MI:SS","STATUS_2":"Completed"};
document.getElementById("btn1").onclick=function(){
var url = (window.location != window.parent.location)
? document.referrer
: document.location.href;
json.PTCC_Accept_DT_1=new Date().format("dd-MM-yy hh:mm:ss");
json.PTCC_Accept_DT_2=new Date().format("dd-MM-yy hh:mm:ss");
json.STATUS_1="Pending IRR"
json.STATUS_2="Pending IRR"
console.log(url);
window.top.postMessage(json,"http://localhost:8080/");
//url只要协议+主机+端口号和父窗口的匹配就行,top表示最上层窗口
//window.parent.postMessage(json,url); parent表示父窗口
//如果确定了窗口的层数,可以使用 window.parent.parent. ... .postMessage(json,url)
}
document.getElementById("btn2").onclick=function(){
var url = (window.location != window.parent.location)
? document.referrer
: document.location.href;
json.PTCC_Accept_DT_1=new Date().format("dd-MM-yy hh:mm:ss");
json.PTCC_Accept_DT_2=new Date().format("dd-MM-yy hh:mm:ss");
json.STATUS_1="Completed - Pending IRR"
json.STATUS_2="Completed - Pending IRR"
console.log(url);
window.parent.postMessage(json,"http://localhost:8080/");
}
document.getElementById("btn3").onclick=function(){
var url = (window.location != window.parent.location)
? document.referrer
: document.location.href;
json.PTCC_Accept_DT_1=new Date().format("dd-MM-yy hh:mm:ss");
json.PTCC_Accept_DT_2=new Date().format("dd-MM-yy hh:mm:ss");
json.STATUS_1="Completed"
json.STATUS_2="Completed"
console.log(url);
window.parent.postMessage(json,"http://localhost:8080/");
}
</script>