Maison > Article > interface Web > PostMessage de communication interdomaine HTML5
En raison de problèmes de sécurité, les documents sous des noms de domaine différents ne sont pas autorisés à accéder aux documents des autres, mais certains Parfois, il est nécessaire de le faire. Par conséquent, nous pouvons généralement utiliser window.name, hash ou jsonp pour obtenir un accès inter-domaines.
Cependant, depuis la sortie du HTML5, nous pouvons avoir une autre façon d'implémenter postMessage. Ce qui suit est l'exemple le plus simple de messagerie. La fonction que nous voulons implémenter est d'envoyer le contenu de la page1 vers une autre page Page2 sous. le nom de domaine, puis page2 affichera le contenu du message correspondant.
Voici plusieurs attributs d'événement importants :
source – source du message, fenêtre d'envoi du message/iframe.
origine – URI de la source du message (peut inclure le protocole, le nom de domaine et le port), utilisé pour vérifier la source de données.
données – les données envoyées par l'expéditeur au destinataire. <br>Ces trois attributs sont des données qui doivent être utilisées dans la transmission des messages.
Nous avons d'abord besoin de deux pages, puis elles doivent être situées sous des noms de domaine différents. Bien sûr, cette machine doit avoir un serveur Web. Ensuite, nous modifierons l'hébergeur pour obtenir des résultats différents. accès au nom de domaine
127.0.0.1 www.postmessage1.com127.0.0.1 www.postmessage2.com
La page d'accueil http://www.php.cn/ contient une iframe intégrée
<!DOCTYPE html><html><head> <title>Html5 postMessage跨文档通信</title></head><body> <input type="text" id="text"> <input type="button" id="send" value="发送"> <iframe id="ifr" src="http://www.postmessage2.com/page2.html"></iframe> <script type="text/javascript"> var text = document.getElementById('text'), send = document.getElementById('send'), ifr = window.frames[0]; //ifr = document.getElementById('ifr').contentWindow; //确保你使用的是iframe的contentWindow属性,而不是节点对象。 send.addEventListener('click',function(){ //主窗口postMessage发送消息给iframe子窗口。 //子窗口通过监听message事件来获得消息 ifr.postMessage(text.value,'http://www.postmessage2.com'); }) </script></body></html>
L'adresse src de l'iframe est http:// www.php.cn/
<!DOCTYPE html><html><head> <title></title></head> <script type="text/javascript"> //在iframe窗口中监听messages事件,并接收消息 window.addEventListener('message',function(event){ var p1 = document.getElementById('p1'); if(event.origin === 'http://www.postmessage1.com'){ p1.innerHTML += event.data +"<br>"; } }) </script><body> <h1>我是一个iframe</h1> <p id="p1"></p></body></html>
Comme beaucoup d'autres technologies Web, si vous ne vérifiez pas la validité de la source de données, utiliser cette technologie deviendra très dangereux ; votre La sécurité de votre application nécessite que vous en soyez responsable. window.postMessage est comme la technologie PHP par rapport à la technologie JavaScript. window.postMessage c'est cool, n'est-ce pas ?
Il en va de même pour la transmission bidirectionnelle de données :
<!DOCTYPE html><html><head> <title>Html5 postMessage跨文档通信</title></head><body> <input type="text" id="text"> <input type="button" id="send" value="发送"> <iframe id="ifr" src="http://www.postmessage2.com/postmessage/iframe01.html"></iframe> <script type="text/javascript"> var text = document.getElementById('text'), send = document.getElementById('send'), // ifr = window.frames[0]; ifr = document.getElementById('ifr').contentWindow; window.addEventListener('message', function(ev){ if(ev.origin === 'http://www.postmessage2.com'){ alert('从'+ ev.origin + '传过来的消息:' + ev.data); } }); send.addEventListener('click',function(){ //主窗口postMessage发送消息给iframe子窗口。 //子窗口通过监听message事件来获得消息 ifr.postMessage(text.value,'http://www.postmessage2.com'); }) </script></body></html>
Le code d'une autre page est le suivant :
<!DOCTYPE html><html><head> <title></title></head> <script type="text/javascript"> //在iframe窗口中监听messages事件,并接收消息 window.addEventListener('message',function(event){ var p1 = document.getElementById('p1'); if (event.origin === 'http://www.postmessage1.com') { p1.innerHTML += "来自窗口" + event.origin + event.data+"<br>" } //像主页面回送消息 event.source.postMessage("你好,这里是:" + this.location, event.origin); }); </script><body> <h1>我是一个iframe</h1> <p id="p1"></p></body></html>
Les canaux de messages fournissent un moyen de communication directe et bidirectionnelle entre les contextes de navigation. Comme la communication interdocuments, le DOM n’est pas directement exposé. Au lieu de cela, chaque extrémité du canal est un port et les données sont envoyées depuis un port et reçues par l’autre port.
Les canaux de messagerie sont utiles, en particulier pour la communication entre plusieurs origines. Veuillez considérer la situation suivante : <br>Renren.com (http://www.php.cn/) intègre en même temps une page de jeu tierce (via iframe, telle que "Renren Restaurant"). -party La page de jeu (http://www.php.cn/) doit obtenir les informations de communication de l'utilisateur à partir d'un autre site Web de carnet d'adresses (http://www.php.cn/). Ce qu'il faut faire?
C'est-à-dire que le site du carnet d'adresses doit envoyer des informations au site du jeu. Selon la communication inter-documents, nous laissons la page parent servir de proxy (c'est-à-dire la page Renren ici) ( similaire à la première démo). Cependant, cette approche signifie que les sites de carnets d'adresses doivent avoir le même niveau de confiance que les pages Renren. Renren, un site de réseau social, doit faire confiance à chaque demande, ou la filtrer pour nous (doit se référer à : précisez une par une).
Cependant, grâce à la communication par canal, le site du carnet d'adresses (http://www.php.cn/) et le site du jeu (http://www.php.cn/) peuvent communiquer directement .
Objets MessageChannel et MessagePort
Lorsque nous créons un objet MessageChannel, nous créons en fait deux ports interconnectés. Un port reste ouvert pour l’expéditeur. L'autre est redirigé vers d'autres contextes de navigation (envoyé par la page parent vers une autre page enfant de l'élément iframe).
var mc = new MessageChannel();
Chaque port est un objet MessagePort, comprenant 3 méthodes disponibles :
postMessage() Envoyer un message via le canal
start() Commencer à répartir les messages reçus sur le port
close() Fermer le port
L'objet MessagePort a également le onmessage event Propriétés qui peuvent être utilisées pour définir des gestionnaires d'événements au lieu d'écouteurs d'événements.
Exemples <br>Je ne comprends même pas le jargon ci-dessus, mais il est plus facile d'en parler avec des exemples.
Créez d'abord trois sites Web, le site Web principal est : http://www.php.cn/, et deux sous-sites Web http://www.php.cn/ et http://www. .cn/. Simulez maintenant le processus de communication entre deux sous-sites :
Condition : Lorsque le sous-site 1 est chargé, envoyez un message au sous-site 2 : "(1) J'ai hâte, ça va ? ? <br>
", lorsque le sous-site 2 reçoit le message, il renvoie le message au sous-site 1, "(2) Ne vous inquiétez pas, il sera bientôt prêt !" Lorsque la sous-page Web 1 reçoit le message du sous-site Web 2, elle renvoie les informations de dialogue à la page principale
Code de la sous-page 1
<!DOCTYPE html><html><head> <title>通道通信子页面iframe01</title></head><body><script type="text/javascript"> window.onload = function(){ var mc, portMessageHandler; mc = new MessageChannel(); portMessageHandler = function(event){ alert(event.data); } //向父页面发送消息以及端口port2 window.parent.postMessage('(1)我已经等不及了,你好了吗?<br>', 'http://localhost/test1/main.html', [mc.port2]); //定义本页面接收到消息后,应该做的处理 mc.port1.addEventListener('message', portMessageHandler, false); //打开本页面的端口,开始监听。。。 mc.port1.start(); }</script></body></html>
Code de la page principale :
<!DOCTYPE html><html><head> <title>messageChannel通信</title></head><body> <h1>通道通信实例</h1> <iframe style="display: none;" src="http://localhost/test1/iframe01.html"></iframe> <iframe style="display: none;" src="http://localhost/test2/iframe02.html"></iframe> <script type="text/javascript"> window.onload = function(){ var iframes, messageHandle; iframes = window.frames; messageHandle = function(event){ if (event.ports.length > 0) { //如果有接收端口,将接收的端口与消息转发给iframe02 iframes[1].postMessage(event.data,'http://localhost/test2/iframe02.html', event.ports); } } //监听第一个页面 window.addEventListener('message',messageHandle,false); } </script></body></html>
Code de la sous-page 2 :
<!DOCTYPE html><html><head> <title>通道通信子页面iframe02</title></head><body><script type="text/javascript"> window.onload = function(){ var messageHandler = function(event){ event.ports[0].postMessage(event.data + "(2)你别急呀,马上就好!"); } //子页面2接收到消息,并将新的消息转发给子页面1 window.addEventListener('message',messageHandler, false); }</script></body></html>
Image du résultat<br>
La démo ci-dessus utilise trois pages : la page principale et deux pages iframe. Parlons de ce que fait chaque page :
La première est la première page iframe : elle comporte trois tâches,
一是创建MessageChannel通道对象;
二是告诉主页面,我加载好了,并把端口传过去;
三是显示发送信息。
//1.创建MessageChannel通道对象mc = new MessageChannel();//2.二是告诉主页面,我加载好了,并把端口传过去;window.parent.postMessage('(1)我已经等不及了,你好了吗?<br>', 'http://localhost/test1/main.html', [mc.port2]);//3.显示发送信息mc.port1.addEventListener('message', portMessageHandler, false); mc.port1.start();
主页面其任务很简单就一个:告诉第二个iframe页面,端口已经打开了(第一个iframe就可以确定跟第二个iframe通信的端口了)。
// 将端口告诉其他文档iframes[1].postMessage(event.data,'http://localhost/test2/iframe02.html', event.ports);
最后就是第二个iframe页面。其任务有两个:一是确定接到的消息与端口;二是将post一个新的数据和此端口保持通信了。
// 1. 接到消息与端口window.addEventListener('message',messageHandler, false);// 2. 与端口建立通道,post一个新的数据port.postMessage(message);
不同域名下的文档因为安全问题,不允许相互之间文档的访问,但是有的时候却不得不需要这样的操作。因此我们一般可以采用 window.name,hash,或者jsonp来实现跨域访问。
不过自从html5出来以后,我们又可以多一种实现方式了postMessage,下面就是一个最简单的消息传递的例子,我们要实现的功能是将page1页面中的内容,发送到不同域名下的page2页面,然后page2将对应消息内容展示出来。
下面是几个比较重要的事件属性:
source – 消息源,消息的发送窗口/iframe。
origin – 消息源的URI(可能包含协议、域名和端口),用来验证数据源。
data – 发送方发送给接收方的数据。 <br>这三个属性是消息传输中必须用到的数据。
首先我们需要两个页面,然后必须分别位于不同的域名下,当然本机肯定要有一个web服务器,接下来就通过修改host来实现不同域名访问
127.0.0.1 www.postmessage1.com127.0.0.1 www.postmessage2.com
主页http://www.php.cn/ 里面嵌套一个iframe框架
<!DOCTYPE html><html><head> <title>Html5 postMessage跨文档通信</title></head><body> <input type="text" id="text"> <input type="button" id="send" value="发送"> <iframe id="ifr" src="http://www.postmessage2.com/page2.html"></iframe> <script type="text/javascript"> var text = document.getElementById('text'), send = document.getElementById('send'), ifr = window.frames[0]; //ifr = document.getElementById('ifr').contentWindow; //确保你使用的是iframe的contentWindow属性,而不是节点对象。 send.addEventListener('click',function(){ //主窗口postMessage发送消息给iframe子窗口。 //子窗口通过监听message事件来获得消息 ifr.postMessage(text.value,'http://www.postmessage2.com'); }) </script></body></html>
iframe框架的src地址为http://www.php.cn/
<!DOCTYPE html><html><head> <title></title></head> <script type="text/javascript"> //在iframe窗口中监听messages事件,并接收消息 window.addEventListener('message',function(event){ var p1 = document.getElementById('p1'); if(event.origin === 'http://www.postmessage1.com'){ p1.innerHTML += event.data +"<br>"; } }) </script><body> <h1>我是一个iframe</h1> <p id="p1"></p></body></html>
跟其他很web技术一样,如果你不校验数据源的合法性,那使用这种技术将会变得很危险;你的应用的安全需要你对它负责。window.postMessage就像是PHP相对于JavaScript技术。window.postMessage很酷,不是吗?
双向数据传输也是一样的:
<!DOCTYPE html><html><head> <title>Html5 postMessage跨文档通信</title></head><body> <input type="text" id="text"> <input type="button" id="send" value="发送"> <iframe id="ifr" src="http://www.postmessage2.com/postmessage/iframe01.html"></iframe> <script type="text/javascript"> var text = document.getElementById('text'), send = document.getElementById('send'), // ifr = window.frames[0]; ifr = document.getElementById('ifr').contentWindow; window.addEventListener('message', function(ev){ if(ev.origin === 'http://www.postmessage2.com'){ alert('从'+ ev.origin + '传过来的消息:' + ev.data); } }); send.addEventListener('click',function(){ //主窗口postMessage发送消息给iframe子窗口。 //子窗口通过监听message事件来获得消息 ifr.postMessage(text.value,'http://www.postmessage2.com'); }) </script></body></html>
另一个页面的代码如下:
<!DOCTYPE html><html><head> <title></title></head> <script type="text/javascript"> //在iframe窗口中监听messages事件,并接收消息 window.addEventListener('message',function(event){ var p1 = document.getElementById('p1'); if (event.origin === 'http://www.postmessage1.com') { p1.innerHTML += "来自窗口" + event.origin + event.data+"<br>" } //像主页面回送消息 event.source.postMessage("你好,这里是:" + this.location, event.origin); }); </script><body> <h1>我是一个iframe</h1> <p id="p1"></p></body></html>
消息通道提供了一个直接,双向浏览上下文之间的通信手段。跟跨文档通信一样,DOM不直接暴露。取而代之,管道每端为端口,数据从一个端口发送,被另一个端口接收,。
消息通道是有用的,特别是跨多个起源的沟通。请考虑以下情形: <br>人人网上(http://www.php.cn/)嵌入了一个第三方的游戏页面(通过iframe的形式,如“人人餐厅”),同时,这个第三方的游戏页面(http://www.php.cn/)又需要从另外一个通讯录网站(http://www.php.cn/)获取用户的通讯信息。咋办?
也就是说通讯录站点要发送信息给游戏站点,根据跨文档通信,我们让父页面作为代理(也就是这里的人人网页面)(类似第一个demo)。然而,这种做法意味着通讯录站点需要有和人人网页面一样的信任级别。人人网这个社交站点需要信任每一个请求,或者为我们过滤(应该指:一个一个指定)。
但是,使用通道通信,通讯录站点(http://www.php.cn/)和游戏站点(http://www.php.cn/)可以直接沟通。
MessageChannel和MessagePort对象
当我们创建了一个MessageChannel对象,我们实际上创造了两个相互关联的端口。一个端口保持开放,为发送端。另外一个被转发到其他浏览上下文(被父页面发送到另外一个iframe元素的子页面中)。
var mc = new MessageChannel();
每一个端口就是一个MessagePort对象,包含3个可用方法:
postMessage() 通过通道发送消息
start() 开始在端口上分派接受的信息
close() 关闭端口
MessagePort对象还有onmessage事件属性,可被用来定义事件句柄而不是事件监听。
实例 <br>上面过于术语的东西我自己都看不明白,还是实例好说话。
首先建立三个网站,其中主网站为:http://www.php.cn/,另外建立两个子网站http://www.php.cn/和http://www.php.cn/。现在来模拟两个子网站之间的通信过程:
需求:当子网站1被加载完成后,向子网站2发送消息:“(1)我已经等不及了,你好了吗?<br>
”,当子网站2接收到消息后,向子网站1返回消息,“(2)你别急呀,马上就好!”。当子网页1接收到子网站2 的消息后,返回给主页面页面对话信息.
子页面1的代码
<!DOCTYPE html><html><head> <title>通道通信子页面iframe01</title></head><body><script type="text/javascript"> window.onload = function(){ var mc, portMessageHandler; mc = new MessageChannel(); portMessageHandler = function(event){ alert(event.data); } //向父页面发送消息以及端口port2 window.parent.postMessage('(1)我已经等不及了,你好了吗?<br>', 'http://localhost/test1/main.html', [mc.port2]); //定义本页面接收到消息后,应该做的处理 mc.port1.addEventListener('message', portMessageHandler, false); //打开本页面的端口,开始监听。。。 mc.port1.start(); }</script></body></html>
主页面的代码:
<!DOCTYPE html><html><head> <title>messageChannel通信</title></head><body> <h1>通道通信实例</h1> <iframe style="display: none;" src="http://localhost/test1/iframe01.html"></iframe> <iframe style="display: none;" src="http://localhost/test2/iframe02.html"></iframe> <script type="text/javascript"> window.onload = function(){ var iframes, messageHandle; iframes = window.frames; messageHandle = function(event){ if (event.ports.length > 0) { //如果有接收端口,将接收的端口与消息转发给iframe02 iframes[1].postMessage(event.data,'http://localhost/test2/iframe02.html', event.ports); } } //监听第一个页面 window.addEventListener('message',messageHandle,false); } </script></body></html>
子页面2的代码:
<!DOCTYPE html><html><head> <title>通道通信子页面iframe02</title></head><body><script type="text/javascript"> window.onload = function(){ var messageHandler = function(event){ event.ports[0].postMessage(event.data + "(2)你别急呀,马上就好!"); } //子页面2接收到消息,并将新的消息转发给子页面1 window.addEventListener('message',messageHandler, false); }</script></body></html>
结果图 <br>
上面的demo动用了三个页面:主页面和两个iframe页面。下面说说每个页面都做了些什么:
首先是第一个iframe页面:其任务有三个,
一是创建MessageChannel通道对象;
二是告诉主页面,我加载好了,并把端口传过去;
三是显示发送信息。
//1.创建MessageChannel通道对象mc = new MessageChannel();//2.二是告诉主页面,我加载好了,并把端口传过去;window.parent.postMessage('(1)我已经等不及了,你好了吗?<br>', 'http://localhost/test1/main.html', [mc.port2]);//3.显示发送信息mc.port1.addEventListener('message', portMessageHandler, false); mc.port1.start();
主页面其任务很简单就一个:告诉第二个iframe页面,端口已经打开了(第一个iframe就可以确定跟第二个iframe通信的端口了)。
// 将端口告诉其他文档iframes[1].postMessage(event.data,'http://localhost/test2/iframe02.html', event.ports);
最后就是第二个iframe页面。其任务有两个:一是确定接到的消息与端口;二是将post一个新的数据和此端口保持通信了。
// 1. 接到消息与端口window.addEventListener('message',messageHandler, false);// 2. 与端口建立通道,post一个新的数据port.postMessage(message);
以上就是html5跨域通信之postMessage的内容,更多相关内容请关注PHP中文网(www.php.cn)!<br>
<br>