• IE6,7通过opener hack方式实现完美跨域


    之前在项目的时候,有需要跨域请求和处理一些大数据量得数据,对于服务端提交的数据非常的之大,get的URL长度限制满足不了需求,又由于跨域的影响,一直很头痛数据传输的问题。于是乎,上网搜了搜一些跨域的解决方案,无非了iframe嵌iframe,通过window.name或者hash,做跳板,都受到url长度的限制,不是很理想。我们都知道在HTML5中,提供了一种postMessage的消息机制,可以在不同域的页面上,互相通过window.postMessage(datastring,’limitDomain’)的方式传递消息。在需要触发的页面注册onMessage事件,event的data属性就是传递datastring文本。再配合老道的JSON.parse就可以完美的传递json格式的对象了。可惜的是目前PostMessage只在IE8,FF和Chrome现版本提供了实现。对于老版本的IE6,7没有提供实现。

    于是在google搜索的时候,无意中发现某高人的Blog提供了一种称之为IE6,7 opener hack的方式实现跨域,据说是google的工程师率先发现的这个bug,fackbook的登陆页面就是利用了这个bug实现了postMessage的跨域。

    可惜,google了半天,详细资料基本找不到,也没有找到一个具体的例子,于是自己捣鼓了一下,写了个例子,放上来。

    下面我们来看下,如何利用这个bug的例子

    hosts配置

       1: 127.0.0.1    www.a.com
       2: 127.0.0.1    www.b.com

    test.htm

       1: <html>
       2: <body>
       3: <iframe id="a" src="http://www.b.com/test1.htm"></iframe>
       4: <script>
       1:  
       2: var i=document.getElementById('a');
       3: i.contentWindow.opener={
       4:     dd:function(str){
       5:         var div=document.createElement('div');
       6:         document.body.appendChild(div);
       7:         div.innerHTML=str;
       8:     }
       9: }
      10: setTimeout(function(){
      11:     opener.bb('bbbbbbb');
      12: },300)
      13:  
    </script>
       5: </body>
       6: </html>

    test1.htm

       1: <html>
       2: <body>
       3:  
       4: <script>
       1:  
       2:     window.opener.dd('aaaaaaaaa');
       3:     parent.opener={
       4:         bb:function(str){
       5:             var div=document.createElement('div');
       6:             document.body.appendChild(div);
       7:             div.innerHTML=str;
       8:         }
       9:     }
    </script>
       5: </body>
       6:  
       7: </html>

    执行http://www.a.com/test.htm就可以看到结果

    我们可以看到,在IE6,7下,只要重置了window对象的opener为一个{}对象,在父页面设置了iframe的window.opener为一个{}之后,在iframe里面就可以通过opener调用parent的方法,在iframe重置parent.opener为一个{}对象之后,在parent就可以调用iframe的方法。

    *还有一种说法是可以设置opener为function(){},通过new opener()来调用

    总结,通过IE6,7的hack,我们可以比较完美的实现postMessage在各大主流浏览器的兼容,以后跨域又多了一项利器。不过比较遗憾的事,重置opener之后,对于window.open打开的窗口,就不能很好的操作了,在IE6,7下。

  • 相关阅读:
    g4e基础篇#1 为什么要使用版本控制系统
    软件开发的自然属性
    定时器实现延时处理
    二分查找法
    php实现循环链表
    redis实现分布式锁
    RabbitMq初探——用队列实现RPC
    RabbitMq初探——发布与订阅
    RabbitMq初探——消息均发
    RabbitMq初探——消息持久化
  • 原文地址:https://www.cnblogs.com/xueduanyang/p/2150090.html
Copyright © 2020-2023  润新知