Heim  >  Artikel  >  Web-Frontend  >  postMessage处理iframe 跨域问题_html/css_WEB-ITnose

postMessage处理iframe 跨域问题_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-24 11:25:381488Durchsuche

背景:由于同源策略存在,javascript的跨域一直都是一个棘手的问题。 父页面无法直接获取iframe内部的跨域资源;同时,iframe内部的跨域资源也无法将信息直接传递给父页面 。

一:传统的解决方式。

传统的iframe资源解决方式:主要通过通过中间页面代理,此处不再赘述,参考 中间页获取跨域iframe

二:html5 postMessage的产生

随着HTML5的发展,html5工作组提供了两个重要的接口: postMessage(send) 和 onmessage 。这两个接口有点类似于websocket,可以实现两个跨域站点页面之间的数据传递。

postMessage API

下面是实践过程中两个小栗子:分别父页面传递信息给iframe,iframe传递信息给父页面。

三:iframe获取父页面信息

话不多说,直接上码:

参考demo: 父页面传给子页面demo

父页面代码

<html><head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">    <title>崔涣 iframe postmessage 父页面</title>    <script type="text/JavaScript">        function sendIt() {            // 通过 postMessage 向子窗口发送数据            document.getElementById("otherPage").contentWindow                    .postMessage(                    document.getElementById("message").value,                    "http://cuihuan.net:8003"            );        }    </script></head><body><!-- 通过 iframe 嵌入子页面 --><iframe src="http://cuihuan.net:8003/test.html" id="otherPage"></iframe><br/><br/><input type="text" id="message"/><input type="button" value="Send to child.com" onclick="sendIt()"/></body></html>

子页面代码

<html>  <head>  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  <title>崔涣测试子页面信息</title>  <script type="text/JavaScript">      //event 参数中有 data 属性,就是父窗口发送过来的数据     window.addEventListener("message", function( event ) {          // 把父窗口发送过来的数据显示在子窗口中       document.getElementById("content").innerHTML+=event.data+"<br/>";      }, false );  </script>  </head>  <body>      this is the 8003 port for cuixiaozhuai      <div id="content"></div>  </body>  </html>

demo 效果如下图:两个跨域页面之间,父页面给子页面传递数据。

四:iframe传递信息给父页面

参考demo: 跨域子页面传给父页面demo

父页面代码

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>崔涣测试父页面</title> <script type="text/JavaScript">     //event 参数中有 data 属性,就是父窗口发送过来的数据     window.addEventListener("message", function( event ) {         // 把父窗口发送过来的数据显示在子窗口中       document.getElementById("content").innerHTML+=event.data+"<br/>";     }, false ); </script> </head> <body>     <iframe src="http://cuihuan.net:8003/iframeSon.html" id="otherPage"></iframe>     <br/>     this is the 1015 port for cuixiaozhuai。     <div id="content"></div> </body> </html>

子页面代码

<html><head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">    <title>崔小涣iframe postmessage 测试页面</title>    <script type="text/JavaScript">        function sendIt() {            // 子页面给父页面传输信息             parent.postMessage(                document.getElementById("message").value,                "http://cuihuan.net:1015"            );        }    </script></head><body><br/>this is the  port for cuixiaozhuai<input type="text" id="message"/><input type="button" value="Send to child.com" onclick="sendIt()"/></body></html>

demo 效果如下图:两个跨域页面之间,子页面传递数据给父页面传递数据。

五:postmessage简单分析和安全问题

postmessage 传送过来的信息如下图,

几乎包含了所有应该有的信息。甚至data中可以包含object,出于安全考虑可以域的校验,数据规则的校验安全校验,如下代码

 window.addEventListener('message', function (event) {                //校验函数是否合法        var checkMessage = function () {            // 只获取需要的域,并非所有都可以跨域            if (event.origin != "need domain") {                return false;            }                        var message = event.data;            // 传输数据类型校验            if (typeof(message) !== 'object') {                return false;            }            // message 的rule中包含xxx则为xxx需要字段。            return message.rule === "xxx";        };        if (checkMessage()) {            // 通过校验进行相关操作            addDetailFunc(event);        }    });

【转载请注明: postMessage处理iframe 跨域问题 | 靠谱崔小拽 】

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn