由于浏览器(同源策略)的限制,JavaScript的跨域问题一直是一个棘手的问题。HTML5提供跨文档消息传输的功能,在web文档之间收发信息。有了这个功能,不仅同一个来源(域端口号)的网页可以相互通信,而且两个不同的域名之间也可以实现跨域通信。
跨文档消息传递提供了在不同web文档之间传输数据的事后消息传递方法,并支持实时消息传递。现在很多浏览器都会支持这个功能,比如Google Chrome 2.0、Internet Explorer 8.0、Firefox 3.0、Opera 9.6、Safari 4.0等。
那么,不支持HTML5的浏览器呢,比如IE6、IE7?
您可以使用window.name方法,因为修改window.name不涉及跨域问题。虽然用起来不理想,但效果还是可以接受的。但是,我们不能每次涉及跨域的时候都写window.postMessage、window.addEventListener、window.name等等。
所以我把整个跨域过程抽象出来,打包成一个JavaScript插件,可以解决双向跨域的问题,实现不同web文档之间的实时通信,实现两个不同域名之间的跨域通信。
演示的下载地址:http://xiazai.jb51.net/201501/other/jcrossdomain_v2.rar,版本v2。
Javascript跨域插件jcrossdomain.js
复制代码如下:(function (win){ /** *不开花的树* 2013/12/07 17:12 */var _ jcd={ isinited : false,elmt: false,hash: ' ',delims : ',',rand : function(){ return(new Date)。getTime() },msg : function(){ alert(' warn :您必须先调用init function ');},init :函数(回调,elmt){ if(_ jcd . Isined==true)返回;_ jcd.isInited=true_ jcd.elmt=elmtIf(win.postMessage){ //浏览器支持HTML5 postMessage方法if(win.addEventListener){ //浏览器支持Firefox、Google等浏览器win.addeventlistener ('message '),函数(ev) {callback.call (win,ev . data);},false);}else if(win.attachEvent){ //支持IE浏览器win.attachevent ('on message ',function (ev) {callback.call (win,ev . data);});} _ jcd . msg=function(data){ _ jcd . elmt . postmessage(data,' * ');} }else{ //浏览器不支持HTML5 postMessage方法,比如IE6,7 setinterval(function(){ if(win . name!==_ jcd . hash){ _ jcd . hash=win . name;callback.call(win,_ jcd . hash . split(_ jcd . delims)[1]);} }, 50);_ jcd . msg=function(data){ _ jcd . elmt . name=_ jcd . rand()_ jcd . delims data;} } } };
var jcd={
initParent :函数(回调,iframeId){ _jcd.init(回调,document . getelementbyid(iframeId))。content WiNDOW);},
initChild :函数(回调){ _jcd.init(回调,win . parent);},
sendMessage :函数(数据){ _jcd.msg(数据);}
};win.jCrossDomain=jcd})(窗口);
父网页中调用的方法:复制代码如下://自定义回调函数varcb=function(msg){ alert(' getmsg 3360 ' msg);};
//初始化并加载回调函数和iframe的idjcrossdomain.initparent (CB,' iframea ');
//发送消息jcross domain . send message(' hello,child ');
子网页中的调用方法:
复制的代码如下://Custom回调函数varcb=function(msg){ alert(' getmsg 3360 ' msg);};
//初始化并加载回调函数jcrossdomain . initchild(CB);
//发送消息jcross domain . send message(' hello,parent ');
模拟提示:为了实现不同域之间的通信,可以在操作系统的hosts文件中添加两个域名进行模拟。
向主机文件中添加两个不同的域名127.0.0.1parent.com 127 . 0 . 0 . 1 child.com。
程的演变: