解决ajax跨域请求 (总结)

ajax跨域请求,目前已用几种方法实现:
 
1)用原生js的xhr对象实现。
               var url="http://freegeoip.net/json/";
              
               //建立xhr对象
               function createCORSXhr(url,method){
                    var xhr=new XMLHttpRequest();
                    if("withCredentials" in xhr){
                              xhr.open(method,url,true);
                         }else if(typeof XDomainRequest !=="undefined"){
                              xhr=new XDomainRequest();
                              xhr.open(method,url);    
                         }else
                              xhr=null;
                         return xhr;                        
                    }
                   
               //建立ajax请求,支持跨域
               function sendAjaxRequest(){
                    var xhr=createCORSXhr(url,"get");
                    xhr.onload=function(){
                         if(xhr.readyState==4){
                         if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
                              alert(xhr.responseText);
                              }else{
                                   alert(" ajax error...")
                                   }
                         }
                    };
                    xhr.onerror=function(){
                         alert("error code:"+xhr.status)
                    }
                    xhr.send(null);
                    };

               sendAjaxRequest()
 
这种方式须要获取相应对象的支持,对于IE,则是XDomainRequest,此种方式cookie不会参与传递。该方式应用了CORS(跨域资源共享)技术,说到底,就是在请求头和响应头中作手脚。在请求头中,加上Origin:协议+域名+端口,固然也能够Origin:null。在响应头中,服务端返回Access-control-Allow-Origin:*.
 
2),经过jsonp数据来实现,说白了,jsonp就是js可执行文件因为<script>和<link>,<img>加载的文件不受同源限制,因此能够经过设置src和href来加载相应的跨域json或者xml数据,可是这种方式须要服务端相配合(服务端须要取出请求字符串中的回调函数名,而且返回给客户端)。jsonp的格式为:回调函数名(jsonData)。
     jQuery中的$.getJSON()默认实现了这种方式,只须要在url?callback=?便可,固然也能够手动指定回调函数名。
 
该种方式必定须要服务端的配合。
 
测试网站: http://freegeoip.net/json/
 
3),第三个就是websocket了,固然须要这样的服务器支持。标准的http服务器是不支持webSocket的。Tomcat7.XX支持websocket。
4),

使用window.name来进行跨域html

window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的全部的页面都是共享一个window.name的,每一个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的全部页面中的,并不会因新页面的载入而进行重置。web

好比:有一个页面a.html,它里面有这样的代码:ajax

QQ截图20130613230631

再看看b.html页面的代码:json

QQ截图20130613230631

a.html页面载入后3秒,跳转到了b.html页面,结果为:跨域

QQ截图20130613230631

咱们看到在b.html页面上成功获取到了它的上一个页面a.html给window.name设置的值。若是在以后全部载入的页面都没对window.name进行修改的话,那么全部这些页面获取到的window.name的值都是a.html页面设置的那个值。固然,若是有须要,其中的任何一个页面均可以对window.name的值进行修改。注意,window.name的值只能是字符串的形式,这个字符串的大小最大能容许2M左右甚至更大的一个容量,具体取决于不一样的浏览器,但通常是够用了。浏览器

上面的例子中,咱们用到的页面a.html和b.html是处于同一个域的,可是即便a.html与b.html处于不一样的域中,上述结论一样是适用的,这也正是利用window.name进行跨域的原理。安全

下面就来看一看具体是怎么样经过window.name来跨域获取数据的。仍是举例说明。服务器

好比有一个www.example.com/a.html页面,须要经过a.html页面里的js来获取另外一个位于不一样域上的页面www.cnblogs.com/data.html里的数据。websocket

data.html页面里的代码很简单,就是给当前的window.name设置一个a.html页面想要获得的数据值。data.html里的代码:cookie

QQ截图20130613230631

那么在a.html页面中,咱们怎么把data.html页面载入进来呢?显然咱们不能直接在a.html页面中经过改变window.location来载入data.html页面,由于咱们想要即便a.html页面不跳转也能获得data.html里的数据。答案就是在a.html页面中使用一个隐藏的iframe来充当一个中间人角色,由iframe去获取data.html的数据,而后a.html再去获得iframe获取到的数据。

充当中间人的iframe想要获取到data.html的经过window.name设置的数据,只须要把这个iframe的src设为www.cnblogs.com/data.html就好了。而后a.html想要获得iframe所获取到的数据,也就是想要获得iframe的window.name的值,还必须把这个iframe的src设成跟a.html页面同一个域才行,否则根据前面讲的同源策略,a.html是不能访问到iframe里的window.name属性的。这就是整个跨域过程。

看下a.html页面的代码:

QQ截图20130613230631

上面的代码只是最简单的原理演示代码,你能够对使用js封装上面的过程,好比动态的建立iframe,动态的注册各类事件等等,固然为了安全,获取完数据后,还能够销毁做为代理的iframe。网上也有不少相似的现成代码,有兴趣的能够去找一下。

相关文章
相关标签/搜索