zoukankan      html  css  js  c++  java
  • ajax 跨域问题

    http://ethanwooblog.iteye.com/blog/670548

    JS的跨域问题,我想很多程序员的脑海里面还认为JS是不能跨域的,其实这是一个错误的观点;有很多人在网上找其解决方法,教其用IFRAME去解决的文章很多,真有那么复杂吗?其实很简单的,如果你用JQUERY,一个GETJSON方法就搞定了,而且是一行代码搞定。

    下面开始贴出方法。

    //跨域(可跨所有域名)

    Js代码  收藏代码
    1. $.getJSON("http://user.hnce.com.cn/getregion.aspx?id=0&jsoncallback=?",function(json){   
    2. //要求远程请求页面的数据格式为: ?(json_data) //例如: //?([{"_name":"湖南省","_regionId":134},{"_name":"北京市","_regionId":143}]) alert(json[0]._name);   
    3. });  

      

     注意,getregion.aspx中,在输出JSON数据时,一定要用Request.QueryString["jsoncallback"],将获取的内容放到返回JSON数据的前面,假设实际获取的值为42342348,那么返回的值就是 42342348([{"_name":"湖南省","_regionId":134},{"_name":"北京市","_regionId":143}])

    因为getJSON跨域的原理是把?随机变一个方法名,然后返回执行的,实现跨域响应的目的。

    具体getJSON的使用说明,请参考JQUERY手册。

    下面一个是跨域执行的真实例子:

    Java代码  收藏代码
    1. <script src="http://common.cnblogs.com/script/jquery.js" type="text/javascript"></script>   
    2. <script type="text/javascript">   
    3. //跨域(可跨所有域名)   
    4. $.getJSON("http://e.hnce.com.cn/tools/ajax.aspx?jsoncallback=?", { id: 0, action: 'jobcategoryjson' }, function(json) { alert(json[0].pid); alert(json[0].items[0]._name); });   
    5.  </script>  

       

    转载自csdn:http://blog.csdn.net/misswuyang/archive/2009/10/23/4718737.aspx

    jQuery跨域原理:

    浏览器会进行同源检查,这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的<Script>标记;我们经常使用<Script>的src属性,脚本静态资源放在独立域名下或者来自其它站点的时候这里是一个url;这个url响应的结果可以有很多种,比如JSON,返回的Json值成为<Script>标签的src属性值.这种属性值变化并不会引起页面的影响.按照惯例,浏览器在URL的查询字符串中提供一个参数,这个参数将作为结果的前缀一起返回到浏览器;

    看下面的例子:

    Java代码  收藏代码
    1. <script type="text/javascript" src="http://domain2.com/getjson?jsonp=parseResponse"> </script>  
    2. 响应值:parseResponse({"Name""Cheeso""Rank"7})  

      

    这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON with padding 上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?


     

    貌似并没有<Script>标记的出现!?OKay,翻看源码来看:

     1 页面调用的是getJSON:
    2 
    3 getJSON: function( url, data, callback ) {
    4         return jQuery.get(url, data, callback, "json");
    5     },
    6 
    7 
    8 继续跟进
    9 
    10         get: function( url, data, callback, type ) {
    11             // shift arguments if data argument was omited
    12              if ( jQuery.isFunction( data ) ) {
    13                 type = type || callback;
    14                 callback = data;
    15                 data = null;
    16             }
    17     
    18             return jQuery.ajax({
    19                 type: "GET",
    20                 url: url,
    21                 data: data,
    22                 success: callback,
    23                 dataType: type
    24             });
    25         
    26  

      


    跟进jQuery.ajax,下面是ajax方法的代码片段:

      1 // Build temporary JSONP function
      2      if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
      3         jsonp = s.jsonpCallback || ("jsonp" + jsc++);
      4 
      5         // Replace the =? sequence both in the query string and the data
      6          if ( s.data ) {
      7             s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
      8         }
      9 
    10         s.url = s.url.replace(jsre, "=" + jsonp + "$1");
    11 
    12         // We need to make sure
    13          // that a JSONP style response is executed properly
    14          s.dataType = "script";
    15 
    16         // Handle JSONP-style loading
    17          window[ jsonp ] = window[ jsonp ] || function( tmp ) {
    18             data = tmp;
    19             success();
    20             complete();
    21             // Garbage collect
    22              window[ jsonp ] = undefined;
    23 
    24             try {
    25                 delete window[ jsonp ];
    26             } catch(e) {}
    27 
    28             if ( head ) {
    29                 head.removeChild( script );
    30             }
    31         };
    32     }
    33 
    34     if ( s.dataType === "script" && s.cache === null ) {
    35         s.cache = false;
    36     }
    37 
    38     if ( s.cache === false && type === "GET" ) {
    39         var ts = now();
    40 
    41         // try replacing _= if it is there
    42          var ret = s.url.replace(rts, "$1_=" + ts + "$2");
    43 
    44         // if nothing was replaced, add timestamp to the end
    45          s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
    46     }
    47 
    48     // If data is available, append data to url for get requests
    49      if ( s.data && type === "GET" ) {
    50         s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
    51     }
    52 
    53     // Watch for a new set of requests
    54      if ( s.global && ! jQuery.active++ ) {
    55         jQuery.event.trigger( "ajaxStart" );
    56     }
    57 
    58     // Matches an absolute URL, and saves the domain
    59      var parts = rurl.exec( s.url ),
    60         remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
    61 
    62     // If we're requesting a remote document
    63      // and trying to load JSON or Script with a GET
    64      if ( s.dataType === "script" && type === "GET" && remote ) {
    65         var head = document.getElementsByTagName("head")[0] || document.documentElement;
    66         var script = document.createElement("script");
    67         script.src = s.url;
    68         if ( s.scriptCharset ) {
    69             script.charset = s.scriptCharset;
    70         }
    71 
    72         // Handle Script loading
    73          if ( !jsonp ) {
    74             var done = false;
    75 
    76             // Attach handlers for all browsers
    77              script.onload = script.onreadystatechange = function() {
    78                 if ( !done && (!this.readyState ||
    79                         this.readyState === "loaded" || this.readyState === "complete") ) {
    80                     done = true;
    81                     success();
    82                     complete();
    83 
    84                     // Handle memory leak in IE
    85                      script.onload = script.onreadystatechange = null;
    86                     if ( head && script.parentNode ) {
    87                         head.removeChild( script );
    88                     }
    89                 }
    90             };
    91         }
    92 
    93         // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
    94          // This arises when a base node is used (#2709 and #4378).
    95          head.insertBefore( script, head.firstChild );
    96 
    97         // We handle everything using the script element injection
    98          return undefined;
    99     }
    100  

    上面的代码第1行到第10行:判断是JSON类型调用,为本次调用创建临时的JsonP方法,并且添加了一个随机数字,这个数字源于用日期值;

    这个地方也就是Taven.李锡远所说的“随机变一个方法名”;

    关注第14行,这一行相当关键,注定了我们的结果最终是<Script> ;然后是构造Script片段,第95行在Head中添加该片段,修成正果;

    不仅仅是jQuery,很多js框架都是用了同样的跨域方案,:)说到这里,嗯,这就是getJSON跨域的原理,赵本山说了“情况呢就是这么个情况”

  • 相关阅读:
    JDBC 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)
    有空必看
    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换
    FusionCharts JavaScript API Column 3D Chart
    FusionCharts JavaScript API
    FusionCharts JavaScript API
    Extjs 继承Ext.Component自定义组件
    eclipse 彻底修改复制后的项目名称
    spring 转换器和格式化
    Eclipse快速生成一个JavaBean类的方法
  • 原文地址:https://www.cnblogs.com/bugY/p/2490205.html
Copyright © 2011-2022 走看看