postMessage
2016-04-05 09:38
369 查看
f.contentWindow.postMessage("SB","http://localhost");
<buttonid="send">SendMessage</button>
<iframeid="receiver"src="http://demos.matt-west.com/post-message/receiver.html"width="400"height="200">
<p>Yourbrowserdoesnotsupportiframes.</p>
</iframe>
window.onload=function(){
//Getthewindowdisplayedintheiframe.
varreceiver=document.getElementById('receiver').contentWindow;
//Getareferencetothe'SendMessage'button.
varbtn=document.getElementById('send');
//Afunctiontohandlesendingmessages.
functionsendMessage(e){
//Preventanydefaultbrowserbehaviour.
e.preventDefault();
//Sendamessagewiththetext'HelloTreehouse!'tothereceiverwindow.
receiver.postMessage('HelloTreehouse!','http://demos.matt-west.com');
}
//AddaneventlistenerthatwillexecutethesendMessage()function
//whenthesendbuttonisclicked.
btn.addEventListener('click',sendMessage);
}
<divid="message"></div>
<scriptsrc="receiver.js"></script>
window.onload=function(){
//Getareferencetothe<div>onthepagethatwilldisplaythe
//messagetext.
varmessageEle=document.getElementById('message');
//Afunctiontoprocessmessagesreceivedbythewindow.
functionreceiveMessage(e){
//Checktomakesurethatthismessagecamefromthecorrectdomain.
if(e.origin!=="http://s.codepen.io")
return;
//Updatethedivelementtodisplaythemessage.
messageEle.innerHTML="MessageReceived:"+e.data;
}
//SetupaneventlistenerthatcallsreceiveMessage()whenthewindow
//receivesanewMessageEvent.
window.addEventListener('message',receiveMessage);
}
《JavaScript标准参考教程(alpha)》,by阮一峰
概述
iframe与主页面的通信
参考链接
window.postMessage方法就是用来在某种程度上,绕过同域限制,实现不同域名的窗口(包括iframe窗口)之间的通信。它的格式如下。
上面代码的targetWindow是指向目标窗口的变量,message是要发送的信息,targetURL是指定目标窗口的网址,不符合该网址就不发送信息,transferObject则是跟随信息一起发送的Transferable对象。
下面是一个postMessage方法的实例。假定当前网页弹出一个新窗口。
上面代码的postMessage方法的第一个参数是实际发送的信息,第二个参数是指定发送对象的域名必须是example.org。如果对方窗口不是这个域名,信息不会发送出去。
然后,在当前网页上监听message事件。
上面代码指定message事件的回调函数为receiveMessage,一旦收到其他窗口发来的信息,receiveMessage函数就会被调用。receiveMessage函数接受一个event事件对象作为参数,该对象的origin属性表示信息的来源网址,如果该网址不符合要求,就立刻返回,不再进行下一步处理。event.data属性则包含了实际发送过来的信息,event.source属性,指向当前网页发送信息的窗口对象。
最后,在popup窗口中部署下面的代码。
上面代码有几个地方需要注意。首先,receiveMessage函数里面没有过滤信息的来源,任意网址发来的信息都会被处理。其次,postMessage方法中指定的目标窗口的网址是一个星号,表示该信息可以向任意网址发送。通常来说,这两种做法是不推荐的,因为不够安全,可能会被恶意利用。
所有浏览器都支持这个方法,但是IE8和IE9只允许postMessage方法与iFrame窗口通信,不能与新窗口通信。IE10允许与新窗口通信,但是只能使用IE特有的MessageChannel对象。
下面是一个LocalStorage的例子。LocalStorage只能用同一个域名的网页读写,但是如果iframe是主页面的子域名,主页面就可以通过postMessage方法,读写iframe网页设置的LocalStorage数据。
iframe页面的代码如下。
主页面的代码如下。
上面的代码已经可以实现,主页面向iframe传入数据。如果还想读取或删除数据,可以进一步加强代码。
加强版的iframe代码如下。
加强版的主页面代码如下。
<buttonid="send">SendMessage</button>
<iframeid="receiver"src="http://demos.matt-west.com/post-message/receiver.html"width="400"height="200">
<p>Yourbrowserdoesnotsupportiframes.</p>
</iframe>
window.onload=function(){
//Getthewindowdisplayedintheiframe.
varreceiver=document.getElementById('receiver').contentWindow;
//Getareferencetothe'SendMessage'button.
varbtn=document.getElementById('send');
//Afunctiontohandlesendingmessages.
functionsendMessage(e){
//Preventanydefaultbrowserbehaviour.
e.preventDefault();
//Sendamessagewiththetext'HelloTreehouse!'tothereceiverwindow.
receiver.postMessage('HelloTreehouse!','http://demos.matt-west.com');
}
//AddaneventlistenerthatwillexecutethesendMessage()function
//whenthesendbuttonisclicked.
btn.addEventListener('click',sendMessage);
}
<divid="message"></div>
<scriptsrc="receiver.js"></script>
window.onload=function(){
//Getareferencetothe<div>onthepagethatwilldisplaythe
//messagetext.
varmessageEle=document.getElementById('message');
//Afunctiontoprocessmessagesreceivedbythewindow.
functionreceiveMessage(e){
//Checktomakesurethatthismessagecamefromthecorrectdomain.
if(e.origin!=="http://s.codepen.io")
return;
//Updatethedivelementtodisplaythemessage.
messageEle.innerHTML="MessageReceived:"+e.data;
}
//SetupaneventlistenerthatcallsreceiveMessage()whenthewindow
//receivesanewMessageEvent.
window.addEventListener('message',receiveMessage);
}
同域限制和window.postMessage方法
来自目录
概述
所谓“同域限制”指的是,出于安全考虑,浏览器只允许脚本与同样协议、同样端口、同样域名的地址进行通信。比如,www1.example.com页面上面的脚本,只能与该域名(相同协议、相同端口)进行通信,如果与www2.example.com通信,浏览器就会报错(不过可以设置两者的document.domain为相同的值)。这是为了防止恶意脚本将用户信息发往第三方网站。window.postMessage方法就是用来在某种程度上,绕过同域限制,实现不同域名的窗口(包括iframe窗口)之间的通信。它的格式如下。
targetWindow.postMessage(message,targetURL[,transferObject]);
上面代码的targetWindow是指向目标窗口的变量,message是要发送的信息,targetURL是指定目标窗口的网址,不符合该网址就不发送信息,transferObject则是跟随信息一起发送的Transferable对象。
下面是一个postMessage方法的实例。假定当前网页弹出一个新窗口。
varpopup=window.open(...popupdetails...); popup.postMessage("HelloWorld!","http://example.org");
上面代码的postMessage方法的第一个参数是实际发送的信息,第二个参数是指定发送对象的域名必须是example.org。如果对方窗口不是这个域名,信息不会发送出去。
然后,在当前网页上监听message事件。
window.addEventListener("message",receiveMessage,false); functionreceiveMessage(event){ if(event.origin!=="http://example.org") return; if(event.data=='HelloWorld'){ event.source.postMessage('Hello',event.origin); }else{ console.log(event.data); } }
上面代码指定message事件的回调函数为receiveMessage,一旦收到其他窗口发来的信息,receiveMessage函数就会被调用。receiveMessage函数接受一个event事件对象作为参数,该对象的origin属性表示信息的来源网址,如果该网址不符合要求,就立刻返回,不再进行下一步处理。event.data属性则包含了实际发送过来的信息,event.source属性,指向当前网页发送信息的窗口对象。
最后,在popup窗口中部署下面的代码。
//popup窗口 functionreceiveMessage(event){ event.source.postMessage("Nicetoseeyou!","*"); } window.addEventListener("message",receiveMessage,false);
上面代码有几个地方需要注意。首先,receiveMessage函数里面没有过滤信息的来源,任意网址发来的信息都会被处理。其次,postMessage方法中指定的目标窗口的网址是一个星号,表示该信息可以向任意网址发送。通常来说,这两种做法是不推荐的,因为不够安全,可能会被恶意利用。
所有浏览器都支持这个方法,但是IE8和IE9只允许postMessage方法与iFrame窗口通信,不能与新窗口通信。IE10允许与新窗口通信,但是只能使用IE特有的
iframe与主页面的通信
iframe中的网页,如果与主页面来自同一个域,通过设置document.domain属性,可以使用postMessage方法实现双向通信。下面是一个LocalStorage的例子。LocalStorage只能用同一个域名的网页读写,但是如果iframe是主页面的子域名,主页面就可以通过postMessage方法,读写iframe网页设置的LocalStorage数据。
iframe页面的代码如下。
document.domain="domain.com"; window.onmessage=function(e){ if(e.origin!=="http://domain.com"){ return; } varpayload=JSON.parse(e.data); localStorage.setItem(payload.key,JSON.stringify(payload.data)); };
主页面的代码如下。
window.onload=function(){ varwin=document.getElementsByTagName('iframe')[0].contentWindow; varobj={ name:"Jack" }; win.postMessage(JSON.stringify({key:'storage',data:obj}),"*"); };
上面的代码已经可以实现,主页面向iframe传入数据。如果还想读取或删除数据,可以进一步加强代码。
加强版的iframe代码如下。
document.domain="domain.com"; window.onmessage=function(e){ if(e.origin!=="http://domain.com"){ return; } varpayload=JSON.parse(e.data); switch(payload.method){ case'set': localStorage.setItem(payload.key,JSON.stringify(payload.data)); break; case'get': varparent=window.parent; vardata=localStorage.getItem(payload.key); parent.postMessage(data,"*"); break; case'remove': localStorage.removeItem(payload.key); break; } };
加强版的主页面代码如下。
window.onload=function(){ varwin=document.getElementsByTagName('iframe')[0].contentWindow; varobj={ name:"Jack" }; //存入对象 win.postMessage(JSON.stringify({key:'storage',method:"set",data:obj}),"*"); //读取以前存取的对象 win.postMessage(JSON.stringify({key:'storage',method:"get"}),"*"); window.onmessage=function(e){ if(e.origin!="http://sub.domain.com"){ return; } //下面会输出"Jack" console.log(JSON.parse(e.data).name); }; };
相关文章推荐
- jQuery技巧之让任何组件都支持类似DOM的事件管理
- 一个war包远程部署的脚本
- 【Java】Integer的常量池
- 第十一天 手机卫士
- Android 内存监测工具 DDMS --> Heap
- chrome官方完整安装包
- 重构的内涵
- List的常用Demo
- PHP QRCODE 彩色二维码
- left join、right join、inner join的区别
- android快速入门
- 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月5日)
- 离开位子,你是谁?(深度好文)
- iperf+sed+gnuplotting查看无线网络速度
- Eclipse--Java注释模板设置详解
- Android 仿新版QQ的tab下面拖拽标记为已读的效果
- Redis 未授权访问漏洞
- python 脚本传递参数
- MyEclipse的 at com.genuitec.eclipse.ast.deploy.core.Deployment.<init>错误解决办法
- MFC控件之进度条