• 解决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=?即可,当然也可以手动指定回调函数名。
     
    该种方式一定需要服务端的配合。
     
     
    3),第三个就是websocket了,当然需要这样的服务器支持。标准的http服务器是不支持webSocket的。Tomcat7.XX支持websocket。
    4),

    使用window.name来进行跨域

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

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

    QQ截图20130613230631

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

    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里的数据。

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

    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。网上也有很多类似的现成代码,有兴趣的可以去找一下。

  • 相关阅读:
    梦断代码,读书计划
    《梦断代码》读后感1
    四则运算2详细过程
    四则运算2初步构思
    四则运算
    阅读《梦断代码》计划
    四则运算2设计思路
    随机输出30道四则运算题
    软件工程阅读计划
    面试题04
  • 原文地址:https://www.cnblogs.com/accordion/p/4092163.html
Copyright © 2020-2023  润新知