html5 도메인 간 통신 postMessage
html5 크로스 도메인 통신에서 postMessage 사용
보안 문제로 인해 서로 다른 도메인 이름의 문서는 서로의 문서에 접근할 수 없지만, 일부 때로는 이렇게 해야 할 때도 있습니다. 따라서 일반적으로 window.name, hash 또는 jsonp를 사용하여 도메인 간 액세스를 달성할 수 있습니다.
그러나 HTML5가 나왔기 때문에 postMessage를 구현하는 방법이 하나 더 있습니다. 다음은 가장 간단한 메시징 예입니다. 우리가 구현하려는 기능은 page1의 콘텐츠를 다른 Page2 페이지로 보내는 것입니다. 도메인 이름을 입력하면 page2에 해당 메시지 내용이 표시됩니다.
다음은 몇 가지 중요한 이벤트 속성입니다.
source – 메시지 소스, 메시지 전송 창/iframe.
origin – 데이터 소스를 확인하는 데 사용되는 메시지 소스의 URI(프로토콜, 도메인 이름 및 포트가 포함될 수 있음).
-
데이터 – 발신자가 수신자에게 보낸 데이터입니다. <br>이 세 가지 속성은 메시지 전송에 반드시 사용해야 하는 데이터입니다.
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 id="我是一个iframe">我是一个iframe</h1> <p id="p1"></p></body></html>
양방향 데이터 전송도 마찬가지입니다:
<!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 id="我是一个iframe">我是一个iframe</h1> <p id="p1"></p></body></html>
메시지 채널은 탐색 컨텍스트 간의 직접적인 양방향 통신 수단을 제공합니다. 문서 간 통신과 마찬가지로 DOM은 직접 노출되지 않습니다. 대신 파이프의 각 끝은 포트이며 데이터는 한 포트에서 전송되고 다른 포트에서 수신됩니다.
메시지 채널은 특히 여러 출처에 걸친 커뮤니케이션에 유용합니다. 다음 상황을 고려해보세요.
Renren.com(http://www.php.cn/)은 제3자 게임 페이지("Renren Restaurant"과 같은 iframe을 통해)를 삽입합니다. -party 게임 페이지(http://www.php.cn/)는 다른 주소록 웹사이트(http://www.php.cn/)에서 사용자의 통신 정보를 얻어야 합니다. 무엇을 해야 할까요? 즉, 주소록 사이트는 문서 간 통신에 따라 상위 페이지(즉, 여기에서는 Renren 페이지) 역할을 하도록 정보를 게임 사이트로 보내야 합니다. 첫 번째 데모와 유사합니다). 그러나 이 접근 방식은 주소록 사이트가 Renren 페이지와 동일한 수준의 신뢰를 가져야 함을 의미합니다. 소셜 네트워킹 사이트인 Renren은 모든 요청을 신뢰하거나 우리를 위해 필터링해야 합니다(참조: 하나씩 지정).
그러나 채널통신을 이용하면 주소록 사이트(http://www.php.cn/)와 게임사이트(http://www.php.cn/)에서 직접 통신이 가능
.
MessageChannel 및 MessagePort 개체
MessageChannel 개체를 생성할 때 실제로 두 개의 상호 연결된 포트가 생성됩니다. 송신 측을 위해 하나의 포트가 열려 있습니다. 다른 하나는 다른 탐색 컨텍스트로 전달됩니다(상위 페이지에서 iframe 요소의 다른 하위 페이지로 전송). var mc = new MessageChannel();
postMessage() 채널을 통해 메시지 보내기
start() 포트에서 수신된 메시지 발송 시작
close() 포트 닫기
MessagePort 개체에도 onmessage 이벤트가 있습니다. 속성, 이벤트 리스너 대신 이벤트 핸들러를 정의하는 데 사용할 수 있습니다.
위의 전문용어는 이해도 못하는데, 예를 들어서 이야기하는 게 더 쉽습니다.
먼저 세 개의 웹사이트를 만듭니다. 기본 웹사이트는 http://www.php.cn/이고 두 개의 하위 웹사이트는 http://www.php.cn/ 및 http://www입니다. .cn/. 이제 두 하위 웹사이트 간의 통신 프로세스를 시뮬레이션합니다.
요구 사항: 하위 웹사이트 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>
<br>
메인 페이지의 코드: <!DOCTYPE html><html><head> <title>messageChannel通信</title></head><body> <h1 id="通道通信实例">通道通信实例</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>
결과 이미지
위 데모에서는 세 페이지(메인 페이지와 두 개의 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的用法
不同域名下的文档因为安全问题,不允许相互之间文档的访问,但是有的时候却不得不需要这样的操作。因此我们一般可以采用 window.name,hash,或者jsonp来实现跨域访问。
不过自从html5出来以后,我们又可以多一种实现方式了postMessage,下面就是一个最简单的消息传递的例子,我们要实现的功能是将page1页面中的内容,发送到不同域名下的page2页面,然后page2将对应消息内容展示出来。
下面是几个比较重要的事件属性:
source – 消息源,消息的发送窗口/iframe。
origin – 消息源的URI(可能包含协议、域名和端口),用来验证数据源。
data – 发送方发送给接收方的数据。
这三个属性是消息传输中必须用到的数据。
首先我们需要两个页面,然后必须分别位于不同的域名下,当然本机肯定要有一个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 id="我是一个iframe">我是一个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 id="我是一个iframe">我是一个iframe</h1> <p id="p1"></p></body></html>
2.通道通信
消息通道提供了一个直接,双向浏览上下文之间的通信手段。跟跨文档通信一样,DOM不直接暴露。取而代之,管道每端为端口,数据从一个端口发送,被另一个端口接收,。
消息通道是有用的,特别是跨多个起源的沟通。请考虑以下情形:
人人网上(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事件属性,可被用来定义事件句柄而不是事件监听。
实例
上面过于术语的东西我自己都看不明白,还是实例好说话。
首先建立三个网站,其中主网站为: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 id="通道通信实例">通道通信实例</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>
结果图
上面的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>

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











HTML의 테이블 테두리 안내. 여기에서는 HTML의 테이블 테두리 예제를 사용하여 테이블 테두리를 정의하는 여러 가지 방법을 논의합니다.

HTML 여백-왼쪽 안내. 여기에서는 HTML margin-left에 대한 간략한 개요와 코드 구현과 함께 예제를 논의합니다.

HTML의 Nested Table에 대한 안내입니다. 여기에서는 각 예와 함께 테이블 내에 테이블을 만드는 방법을 설명합니다.

HTML 테이블 레이아웃 안내. 여기에서는 HTML 테이블 레이아웃의 값에 대해 예제 및 출력 n 세부 사항과 함께 논의합니다.

HTML 입력 자리 표시자 안내. 여기서는 코드 및 출력과 함께 HTML 입력 자리 표시자의 예를 논의합니다.

HTML 순서 목록에 대한 안내입니다. 여기서는 HTML Ordered 목록 및 유형에 대한 소개와 각각의 예에 대해서도 설명합니다.

HTML에서 텍스트 이동 안내. 여기서는 Marquee 태그가 구문과 함께 작동하는 방식과 구현할 예제에 대해 소개합니다.

HTML onclick 버튼에 대한 안내입니다. 여기에서는 각각의 소개, 작업, 예제 및 다양한 이벤트의 onclick 이벤트에 대해 설명합니다.
