javascript和jquery下跨域的实现

js下跨域的问题很让人头疼,本文讨论如何在javascript下实现跨域访问,以及如何利用jquery来实现跨域访问。

1,javascript下的跨域访问

1)实现基本原理

在html的DOM节点中,<script>节点是可以访问跨域服务器上的数据的,因此可以通过指定<script>的src属性值为跨域的服务器的url,从而实现跨域访问。

但是这个url的返回值不能是单纯的诸如{id:1, name: 'shyman', age: 18, male:true}格式的json对象

设想一下,假如有一个名为example.js的javascript文件,该javascript里面的内容是{id:1, name: 'shyman', age: 18, male:true},

当我们通过<script type="text/javascript"  src="example.js"></script>去引用这个javascript的时候,可以说这个被引用的js没有任何一点作用,或者说我们根本访问不到js里面的内容。

 

怎么办??

 

于是,于是。。 如果上面的example.js里面的内容是var json = {id:1, name: 'shyman', age: 18, male:true}; callback(json);

或者是callback({id:1, name: 'shyman', age: 18, male:true});这样的js才有意义嘛,这才是一个正常的js嘛。。

注意上面这种数据格式,它在json的外面添加了一个函数callback,我们称这种数据格式为jsonp、或者json-p,翻译起来就是"填充了的json"(json with padding) ,这种叫法我们暂时可以不管。

 

现在我们正常的引用了example.js,有一个问题,js中的callback这个方法我们并没有定义,如果只引用这个js的话,浏览器肯定会提示脚本错误。

为了让浏览器不报脚本错误,同时也为了执行这个callback方法,在引入example.js脚本之前,我们要在另一个js中对callback方法进行定义,比如

function callback(data)
{
     var ret = "";
     for ( var pro  in data)
        ret += pro + ":" + data[pro] + "\n";
    alert(ret);
}

这个时候在页面刚打开的时候,会弹出从服务器上取回的jsonp数据中的json数据信息。

这样一个简单的js跨域就实现了。。

 

对了,对了。。还有刚开始提到的"<script>的src属性值为跨域的服务器的url",这个跨域的url返回值如何构造呢,以servlet服务为例。

在servlet的get和post方法中如下方式构造返回字符串就可以了

response.getWriter().write("callback({id: 1, name: 'shyman', age: 18, male:true});");

 

2)改进实现

如上1)所述,其实已经实现了基本的js跨域,在实际应用中,不可能像1)那样页面一加载完,就立即去跨域的服务器取jsonp数据,而是需要调用的时候去取。

其实很简单,首先定义callback方法(当然也可以是其他名字的方法,如xxx方法),然后动态地创建一个<script>元素,指定其url(该url返回值必须是由callback或xxx填充json的jsonp格式数据),并且动态地加入到<head>节点下。ok,就这么简单

< html >
< head >
< meta  http-equiv ="Content-Type"  content ="text/html;charset=gb2312" >
< title >javascript crossdomain </ title >
< script  type ="text/javascript" >
var  script  =  document.createElement( " script " );
script.type 
=   " text/javascript " ;

var  uid;
var  url  =   " http://localhost:8080/xtgeomaps_app/CrossDomain " ;
var  jsonpCallback  =   " xxx " ;

function  query()
{
    uid 
= document.getElementById("us erid " ).value;
    doQuery(uid, url, jsonpCallback);
}
function  doQuery(_uid, _url, _jsonpCallback)
{
    script.src 
=  _url  +   " ?_uid= "   +  _uid  +   " &_jsonpCallback= "   +  _jsonpCallback; // 返回字符串xxx({id:1, name: 'shyman', age: 18, male:true});
     var  head  =  document.head  ||  document.getElementsByTagName(  " head "  )[ 0 ||  document.documentElement;
    
if  ( head  &&  script.parentNode ) {
        head.removeChild( script );
    }
    head.insertBefore( script, head.firstChild );
}
function  xxx(data)
{
    
var  ret  =   "" ;
    
for  ( var  pro  in  data)
        ret 
+=  pro  +   " : "   +  data[pro]  +   " \n " ;
    alert(ret);
}
</ script >
</ head >
< body >
输入要查询的id: < input  id ="userid"   />< br />< br />
< input  type ="button"  value ="javascript跨域访问"  onclick ="query(uid, url, jsonpCallback)"   />
</ body >
</ html >

跨域服务器servlet的代码为

protected  void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {
        String uid = request.getParameter("_uid");
        String jsonpCallback = request.getParameter("_jsonpCallback");
        response.getWriter().write(jsonpCallback + "({id:" + uid + ", name: 'shyman', age: 18, male:true});"); // 构造javascript的执行函数字符串
    }

js的跨域就搞定了

2,jquery跨域实现

其实上面js跨域的实现借鉴了jquery的实现方法,实现方法如下

< head >
< meta  http-equiv ="Content-Type"  content ="text/html;charset=gb2312" >
< title >jquery crossdomain </ title >
< script  type ="text/javascript"  src ="jquery-1.7.2.min.js" ></ script >
< script  type ="text/javascript" >
function  query()
{
    
var  uid  = $("#userid").val();

    $.ajax({
            url: 
' http://localhost:8080/xtgeomaps_app/CrossDomain ' ,
            data: {_uid: uid},
            dataType: 
' jsonp ' ,
            jsonp: 
" _jsonpCallback " ,
            
// jsonpCallback: "xxx",
            success:  function  (json) { // json={id:1, name: 'shyman', age: 18, male:true}
                 var  ret  =   "" ;
                
for  ( var  pro  in  json)
                    ret 
+=  pro  +   " : "   +  json[pro]  +   " \n " ;
                alert(ret);
            },
            error: 
function (jqXHR, textStatus, errorThrown){ 
                alert(textStatus); 
            } 
        });
        
}
</ script >
</ head >
< body >
输入要查询的id: < input  id ="userid"   />< br />< br />
< input  type ="button"  value ="jquery跨域访问"  onclick ="query()"   />
</ body >
</ html >

跨域服务器端代码同1中的代码

 

总结一下吧,所谓js跨域,并不是所有的域都能跨,如果跨域服务器返回的不是jsonp数据格式,基本很难通过js跨域。

js跨域实现不了,怎么办?呵呵,那就只能通过自己写代理的方式了

 

 

 

 

 

 

 

 

你可能感兴趣的:(JavaScript)