前端跨域技术之跨文档消息传输

来源:互联网 发布:淘宝男风时尚生活假货 编辑:程序博客网 时间:2024/05/23 01:19

跨文档消息传送,简称为XDM,指的是来自不同的域的页面间的传递消息。 如果两个网页不同源,就无法拿到对方的DOM。典型的例子是iframe窗口和window.open方法打开的窗口,它们与父窗口无法通信。

   比如,父窗口运行下面的命令,如果iframe窗口不是同源将会报错。

 document.getElementById("iframe").contentWindow.document

   上面命令中,父窗口想获取子窗口的DOM,因为跨源导致报错。

   反之亦然,子窗口获取主窗口的DOM也会报错。

window.parent.document.body

   如果两个窗口一级域名相同,只是二级域名不同,那么设置document.domain属性,就可规避同源政策,拿到DOM。而 对于完全不相同的网站,目前有三种方法,可以解决跨域窗口的通信问题。

  (1) 片段识别符(fragment identifier

    片段识别符指的是,URL#号后面的部分,即hash部分,比如http://qq.com/x.html#fragment的#fragment。如果只是改变片段标识符,页面将不会重新刷新,父窗口可以把信息,写入子窗口的片段标识符。

 var src = originURL+'#'+data;

 document.getElementById('iframe').src = src;

  子窗口通过监听hashchange事件得到通知

 window.onhashchange = checkMessage;

 function checkMessage(){

 var message = window.location.hash;

 //...

 }

 同样的,子窗口也可以改变父窗口的片段标识符。

 parent.location.href = target+"#"+hash; 

  (2) window.name

     浏览器窗口有window.name属性。这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置这个属性,后一个网页就可以读取它

 父窗口先打开一个子窗口,载入一个不同源的网页,该网页将信息写入window.name属性。

 window.name = data;

 接着,子窗口跳回一个与主窗口同域的网址。

 location = 'http://parent.url.com/xxx.html';

 然后,主窗口就可以读取子窗口的window.name了。

 var data = document.getElementById('iframe').contentWindow.name;

 这种方法的优点是,window.name容量很大,可以放置非常长的字符串;缺点是必须监听子窗口window.name属性的变化,会影响网页性能。

(3) 跨文档通信APICross-document messaging

         上面两种方法都属于破解,HTML5为解决这个问题,引入一个全新的API:跨文档通信APICross-document messaging

 这个APIwindow对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。postMessage()方法接收两个参数:一条消息和一个表示消息接收方来自哪个域的字符串,第二个参数对保障安全通信非常重要,可以防止浏览器把消息发送到不安全的地方。 举例来,父窗口http://aaa.com向子窗口http://bbb.com发送消息,调用postMessage方法即可。 

 var popup =window.open('http://aaa.com','title');

 popup.postMessage('Hello World!','http://aaa.com');

 

 postMessage方法的第一个参数是具体的信息内容,第二个参数是接受消息的窗口的源(origin),即协议+域名+端口。也可以设为“*”,表示不限制域名,向所有窗口发送。

 子窗口父窗口发型消息的写法类似。 

window.opener.postMessage('Nice to see you','http://bbb.com'); 

接收到XDM的消息时,会触发window对象的message事件,这个事件以异步形式触发,所以可能会发生一些延迟。  触发message事件后,传递给onmessage处理程序的事件对象event包含以下三方面的重要信息

(1).event.source:发送消息的窗口

(2).event.origin:消息发向的网站

(3).event.data:消息内容


父窗口和子窗口可以通过message事件,监听对方的消息。 

window.addEventListener('message',function(e){

 console.log(e.data);

},false);

 


下面的例子是,子窗口通过event.source属性应用父窗口,然后发送消息。 

window.addEventListener('message',receiveMessage);

function receiveMessage(event){

   event.soure.postMessage('Nice to see you!','*');

}

event.origin属性可以过滤不是发给本窗口的消息。

window.addEventListener('message',receiveMessage);

function receiveMessage(event){

 if(event.orgin !== 'http://bbb.com') return;

 if(event.data === 'Hello World'){

   event.soure.postMessage('Hello',event.source); 

}else{

   console.log(event.data);

 }

}

 


     片段识别符指的是,URL#号后面的部分,比如http://qq.com/x.html#fragment的#fragment。如果只是改变片段标识符,页面将不会重新刷新、

  父窗口可以把信息,写入子窗口的片段标识符。

  var src = originURL+'#'+data;

  document.getElementById('iframe').src = src;

  子窗口通过监听hashchange事件得到通知

  window.onhashchange = checkMessage;

  function checkMessage(){

  var message = window.location.hash;

  //...

 }

 同样的,子窗口也可以改变父窗口的片段标识符。

 parent.location.href = target+"#"+hash;

 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 白色T恤衫上沾上黑色的黄油怎么办 家教遇到成绩好的学生该怎么办 跟越南人离婚孩子中国户口9怎么办 老婆是个越南人至今没户口怎么办 等离子屏z板链接处排线打火怎么办 等离子自动调焊的成形不好怎么办 村里内村道路中间被抢占了怎么办 华为换电池之后卡没反应怎么办 汽车钥匙换电池后没反应怎么办 汽车解锁换电池后没反应怎么办 包裹显示待收件人向海关申报怎么办 在越南签证被公安扣了怎么办 酷派手机收不到验证码怎么办 苹果想把图片上的字盖上怎么办 婴儿自己把眼珠子抠红了怎么办 如果美陆战队员进入台湾那怎么办? 顺产生完小孩吸不通奶怎么办 耐克空军一号白色底发黄怎么办 中行网银u盾丢了怎么办 有人用你的手机号码不停注册怎么办 获得公开你微信头像的权限是怎么办 手机能进的网站电脑进不去怎么办 苹果8p下不了微信怎么办 苹果手机版本过底不能下微信怎么办 手机打开视频跳转到qq是怎么办 淘宝店铺显示服务竟然出错了怎么办 母羊下完羊羔把羊衣吃了怎么办? 移植后56天有黑色东西怎么办 我家的金丝熊浑身都是尿怎么办 一键启动车钥匙丢了怎么办 把爷爷的遗物弄丢了怎么办 如果你娶了一个傻子你怎么办 在国外订机票手机收不到信息怎么办 网上买机票名字写错了怎么办 买机票名字错了一个字怎么办 微店没收到货却显示已收货怎么办? 手机存的照片误删了怎么办 魔兽世界把要用的装备分解了怎么办 邻居家的狗见到我就叫怎么办 我的世界玩的时间长会卡应该怎么办 网易我的世界密码账号都忘了怎么办