HTML5 postMessage Iframe跨域传递信息

一、问题

平时做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>

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值