1、跨域ajax前台
对ajax有一定了解的程序员都应该知道,一般的ajax是不能跨域获取数据的。那么对应ajax跨域的技术手段便是jsonp。jsonp的原理网上有就很多的资料,我们都知道<script>和<img>等标签是具有跨域能力的,这里所说的跨域能力是指:
<script type="text/javascript" src="http://static.blog.csdn.net/scripts/jquery.js"></script> <img src="//www.baidu.com/img/bdlogo.png"/>
jsonp大致上就是利用<script>的跨域能力来提供ajax的跨域访问,添加一个回调函数的参数,发送ajax请求后立即调用回调函数处理数据。
下面看具体的示例:
(1) $.ajax()
$.ajax({ type: "get",async: false,url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",dataType: "jsonp",jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:"myfunction",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function(json){//对返回数据进行处理。如果没有定义jsonpCallback,则可以在这里处理。如果定义了jsonpCallback,则可以不处理,因为在请求到数据后,会自动调用myfunction(result)其实这里发送的请求实际上是
http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=myfunction
如果没有定义jsonCallback,那么请求则是:
<http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=?
这里的"?",jquery会自动将其转换为一个随机的参数,模拟函数名。
<script> function myfunction(result) { //进行处理 } </script>
值得注意的是:
dataType: "jsonp"
这是十分重要的,告诉请求的数据是jsonp,否则请求将不会携带参数callback=myfunction
(2) $.getJson()
事实上,对于$.getJson()是不能跨域的。我在网上看到很多说$.getJson()跨域的示例,后来实验了一下,实际上getJson是不具备跨域能力的。主要是因为getJson()请求的数据类型是json格式。
jQuery.getJSON(url,data,success); // 等价于 $.ajax({ url: url,type: "GET",data: data,success: success,dataType: "json" });我将$.getJson()分为两种情况: @H_404_45@a、$.getJson("http://....?callback=myfunction",function(data){}) 对于这种类型的ajax请求,由于请求的数据默认是json格式,但是由于后台返回的不是json格式(关于如何写可以跨域请求的服务,后面会提到),所以连数据都请求不到。 @H_404_45@b、$.getJson("http://....?callback=?",function(data){})
对于这种类型的ajax请求,确实会得到正确的数据,但是不会执行function(data)函数,至于到底是什么原因,我也弄不明白。
其他类似的$.postJson()等也是不能跨域的。
综上所述,要想使用ajax跨域请求,最好是:
(1)javascript,创建XMLHTTPRequest (2)$.ajax(),设置datatype (3)<script src="http://.....?callback=myfunction"></script>
2、支持回调函数的后台
前面提到了$.ajax()在请求到数据后会自动调用回调函数myfunction(result)来处理数据,这是需要后台支持的。如果没有后台的支持,那么则需要在success: function(json){}中进行处理。有了回调函数,就没有必要了。public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string result = "{\"name\":\"mcfer\",\"age\":\"18\",\"sex\":\"male\"}"; if (context.Request["callback"] != null) { context.Response.Write(context.Request["callback"].ToString() + "(" + result + ")");//这里相当于返回了一段JavaScript代码到前端执行 } else context.Response.Write(result); }
需要注意的是一定要先获取callback参数。而且在前台的请求参数名称也一定要是callback
从后台我们可以看到实际上我们请求获取的数据是 "函数名(数据)",所以在前台会自动执行这个函数。那么还有一个疑问:我们在
success: function(json){}中处理的数据"json"是没有函数名的,只有里面的数据,我猜想这应该是jsonp做出的优化处理,自动将函数名去掉了。