zoukankan      html  css  js  c++  java
  • JavaScript跨域解决办法

    在找到跨域解决办法之前,我们要先弄清楚一些基本概念

    • 什么是跨域?
    • 什么是“同源策略”?
    • 跨文档消息通信 & 跨域请求数据
    • 主域相同而子域不同
    • 不同域名的跨域访问

    什么是跨域?

    简单地理解就是因为同源策略的限制,a.com 域名下的js无法操作b.com或是xx.a.com域名下的对象。那么什么是“同源策略”?
     

    什么是同源策略?

         源是在网络上用来建立信任关系的地址子集。源由规则(scheme)、主机(host)、端口(port)组成。例如,由于规则不同(如https与http),所以 http://www.a.com与 https://www.a.com页面的源是不同的。
    (有关这部分的内容,特别推荐Rain Man大哥写的这一篇,非常清晰易懂:http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html
     
         同源策略是指出于安全方面的考虑,运行在同一浏览器中的框架、标签页、窗口间的通信受到了严格的限制。源不同,则检索或修改其他源的内容时,浏览器会抛出安全异常,并阻止相应的操作。在html5 新的api出现以前,只有同源的页面才可以相互访问对象。 
     
    其实跨域通信是分为两部分来讲的:
    • 跨文档消息通信 (如读取不同源页面的DOM对象等)
    • 跨域请求数据(跨域ajax请求, jsonp请求等)
    注:实现跨域请求服务器数据 有很多种方式,如jsonp请求,flash等。本文主要讲“跨文档消息通信” 

    跨文档消息通信

           我们经常在工作中碰到的有两种:

    • 主域相同而子域不同

        可以通过设置document.domain+iframe的办法来解决 

    • 不同域名的跨域访问

             解决方案有很多,例如:

            1. iframe+代理页+hash的方式

            2. iframe + name

            3. postMessage 


    下面我们用个例子来实现 “跨文档消息通信”

    需求:a页面里有一个iframe(b页面)。当b页面加载完成后,同步一下iframe的高度。 

    1、“主域相同而子域不同” 的情况

         下次上代码

    2、“不同域名的跨域访问” 的情况

    iframe+代理页+hash的方式:利用proxy.html代理页来实现. 这个办法比较绕,但是可以解决完全跨域情况下的脚步置换问题。原理是利用location.hash来进行传值原理及流程。来张我画的草图:

    a页面,位于sport.taobao.com域名下 

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="gbk" />
     5 <script src="http://a.tbcdn.cn/s/kissy/1.3.0/kissy-min.js"></script>
     6 <style>
     7 body{background:#00ae8f;}
     8 .iframeArea{margin-top:30px;}
     9 </style>
    10 </head>
    11 <body>     
    12     A:运动页面 此页面访问时的url是这样的:
    13     http://sport.taobao.com/market/sports/a.php?iframeUrl=http://wanke.etao.com/mobile/product-600000000007215.html
    14     <div class="iframeArea">
    15         <iframe id="J_sport_iframe" name="sport_iframe" src="" frameborder="0" style="display: block; margin: 0 auto; height: 1000px;" width="990" scrolling="no" >
    16         </iframe>
    17     </div>
    18     <script>
    19         (function(S){
    20             KISSY.use('uri',function(S,Uri){
    21                 var url = new Uri(location.href).getQuery().get('iframeUrl');
    22                 if(url){
    23                     S.all('#J_sport_iframe').attr("src",url);    //给iframe赋src的值
    24                 }else{
    25                     S.all('#J_sport_iframe').attr("src","http://wanke.etao.com/error.html");
    26                 }
    27             });
    28         })(KISSY);
    29     </script>
    30 </body>
    31 </html>
    View Code

    b页面位于wanke.etao.com域名下

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="gbk" />
    <script src="http://a.tbcdn.cn/s/kissy/1.3.0/kissy-min.js"></script>
    </head>
    <body>     
    <div>
    我是玩客页面:http://wanke.etao.com/mobile/product-600000000007215.html
    </div>   
    <script>
        /*
       etao的B.html js 写在页面结束时
       */
      (function (S) {
        if (window != top) {
            //在etao的页面B.html中创建iframe代理
            S.one('body').append('<iframe id="iframeproxy" name="iframeproxy" src="" width="0" height="0" style="display:none;" ></iframe>');
            
            function updateHeight() {
                if (window !=top && S.one("#iframeproxy")) {
                    var ht = S.one("body").height() + 10, a = window.name, b;
                    b = "http://sport.taobao.com/market/sports/iframe-proxy2.php"
                    S.one("#iframeproxy")[0].src = b + "#" + ht;
                }
            }
            updateHeight();
            S.one(window).on('load', function () {
                updateHeight();
            });
        }
    })(KISSY); 
    </script>
    </body>
    </html>
    View Code

    proxy页面位于sport.taobao.com域名下,但是插入到b页面中

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="gbk" />
     5 <script src="http://a.tbcdn.cn/s/kissy/1.3.0/kissy-min.js"></script>
     6 </head>
     7 <body>     
     8     <script>
     9     /*
    10     taobao站点页面中的js http://sport.taobao.com/market/baobao/iframe-proxy2.php
    11     */
    12     (function(S){        
    13         function pseth() {
    14           var iObj = window.top.document.getElementById('J_sport_iframe');//A和iframe-proxy2同域,所以可以访问节点
    15           iObjH = window.location.hash;//访问自己的location对象获取hash值
    16           iObj.style.height = (+iObjH.split("#")[1]+5)+"px";//操作dom
    17         }
    18         pseth();
    19         S.all(window).on("hashchange",function(){
    20             pseth();
    21         });
    22 
    23     })(KISSY);
    24     </script>
    25 </body>
    26 </html>
    View Code

    3. postMessage

      我这里有篇文章专门写postMessage做跨域的。请看 http://www.cnblogs.com/summer_shao/p/3998695.html

  • 相关阅读:
    Input file 调用相机
    C#读取txt文件
    高并发下获取随机字符串
    将Datatable转换为Json数据
    System.IO.Path 获得文件的后缀名
    用Js写的贪吃蛇游戏
    C#中的事件
    通过一个控制台小Demo--算术题,来展示C#基本的程序结构
    数据库高级应用之游标
    数据库高级应用之事务
  • 原文地址:https://www.cnblogs.com/summer_shao/p/proxy.html
Copyright © 2011-2022 走看看