设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

父子页面之间跨域通信的方法

2014-8-12 09:42| 发布者: joejoe0332| 查看: 5515| 评论: 0|原作者: lyndon|来自: 腾讯TID

摘要: 由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案。之前也有小网同学分享过一篇“跨域,不再纠结” 开始照着尝试时还是有些不 ...

  好吧,现在我必须把话锋调转一下了。前面讲的这么多,也只是抛出来一些之前我们可能会采用的跨域通信方法,事实上代理页面、url传参数和window.name、甚至还有一些利用url的hash值的跨域传值方法,都能百度到不少相关资料。但它们都逃不开代理页面,也就不可避免的要产生网络请求,而事实上这并不是我们的本意,我们原本希望它们能够直接在客户端通信,避免不必要的网络请求开销——这些开销,在访问量超大的站点可能会对服务器产生相当大的压力。那么,有没有更完美一点的替代方案呢? 必须给大家推荐postMessage。postMessage 正是为了满足一些合理的、不同站点之间的内容能在浏览器端进行交互的需求而设计的。利用postMessage API实现跨域通信非常简单,我们直接看一下实例的代码: 代码片段五,A.com/a.html

02<head runat="server">
03    <title>A.com/a.html</title>
04    <script type="text/javascript">
05        var trustedOrigin = "<a href="http://localhost:8091/">http://localhost:8091</a>";
06 
07        function messageHandler(e) {
08            if (e.origin == trustedOrigin) {//接收消息的时候,判断消息是否来自可信的源,这个源是否可信则完全看自己的定义了。
09                showMsg(e.data);//e.data才是真实要传递的数据
10            } else {
11                // ignore messages from other origins
12            }
13        }
14 
15        function sendString(s) {//发送消息
16            document.getElementById("widget").contentWindow.postMessage(s, trustedOrigin);
17        }
18 
19        function showMsg(message) {
20            document.getElementById("status").innerHTML = message;
21        }
22 
23        function sendStatus() {
24            var statusText = document.getElementById("statusText").value;
25            sendString(statusText);
26        }
27 
28        function loadDemo() {
29            addEvent(document.getElementById("sendButton"), "click", sendStatus);
30            sendStatus();
31        }
32 
33        function addEvent(obj, trigger, fun) {
34            if (obj.addEventListener) obj.addEventListener(trigger, fun, false);
35            else if (obj.attachEvent) obj.attachEvent('on' + trigger, fun);
36            else obj['on' + trigger] = fun;
37        }
38        addEvent(window, "load", loadDemo);
39        addEvent(window, "message", messageHandler);
40 
41    </script>
42</head>
43<body>
44    <h1>A.com/a.html</h1>
45    <p><b>源</b>: <a href="http://localhost:8090</p">http://localhost:8090</p</a>>
46    <input type="text" id="statusText" value="msg from a.com/a.html">
47    <button id="sendButton">向b.com/b.html发送消息</button>
48    <p>接收到来自a.com/a.html的消息: <strong id="status"></strong>.<p>
49    <iframe id="widget" width="800" height="400" src="<a href="http://localhost:8091/PostMessage/Default.aspx%22%3E%3C/iframe">http://localhost:8091/PostMessage/Default.aspx"></iframe</a>>
50</body>
51</html>

代码片段六,B.com/b.html

02<head runat="server">
03    <title>B.com/b.html</title>
04    <script type="text/javascript">
05        //检查postMessage 是否可以用:window.postMessage===undefined
06        //定义信任的消息源
07        var trustedOrigin = "<a href="http://localhost:8090/">http://localhost:8090</a>";
08        function messageHandler(e) {
09            if (e.origin === "<a href="http://localhost:8090/">http://localhost:8090</a>") {
10                showMsg(e.data);
11            } else {
12                // ignore messages from other origins
13            }
14        }
15 
16        function sendString(s) {
17            window.top.postMessage(s, trustedOrigin); //第二个参数是消息传送的目的地
18        }
19 
20        function loadDemo() {
21            addEvent(document.getElementById("actionButton"), "click", function () {
22                var messageText = document.getElementById("messageText").value;
23                sendString(messageText);
24            });
25        }
26 
27        function showMsg(message) {
28            document.getElementById("status").innerHTML = message;
29        }
30 
31        function addEvent(obj, trigger, fun) {
32            if (obj.addEventListener) obj.addEventListener(trigger, fun, false);
33            else if (obj.attachEvent) obj.attachEvent('on' + trigger, fun);
34            else obj['on' + trigger] = fun;
35        }
36        addEvent(window, "load", loadDemo);
37        addEvent(window, "message", messageHandler);
38    </script>
39</head>
40<body>
41    <h1>B.com/b.html</h1>
42    <p><b>源</b>: <a href="http://localhost:8091</p">http://localhost:8091</p</a>>
43    <p>接收到来自a.com/a.html的消息: <strong id="status"></strong>.<p>
44            <div>
45                <input type="text" id="messageText" value="msg from b.com/b.html">
46                <button id="actionButton"> 向a.com/a.html发送一个消息</button>
47            </div>
48</body>
49</html>


  代码的关键是message事件是一个拥有data(数据)和origin(来源)属性的DOM事件。data属性是发送的实际数据,origin属性是发送来源。Origin属性很关键,有了这个属性,接收方可以轻易的忽略掉来自不可信源的消息,也就能有效避免跨域通信这个开口给我们的源安全带来的隐患。接口很强大,所以代码很简单。我们可以抓包看一下,这个通信过程完全是在浏览器端的,没有产生任何的网络请求。同时这个接口目前已经得到了绝大多数浏览器的支持,包括IE8及以上版本,参见下面的图表:


图7

  但是为了覆盖ie6等低版本浏览器,我们完整的方案里面还是要包含一下兼容代码,就是最开始介绍的代理页面的方法了,但必须是以postMessage为主,这样即便最后会有某些浏览器因为这种通信产生一些网络请求,比例也是非常低的了。


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部