ajax跨域问题

ajax自己其实是经过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不容许js代码进行跨域操做,会警告,因此才出现ajax跨域的问题。javascript

配置Web服务器支持跨域访问html

这里描述以Tomcat为Web服务器状况下的解决办法,在Java Web程序的WEB-INF下的web.xml文件中加入以下配置便可。java

1
2
3
4
5
6
7
8
9
<!--cors filter-->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

注意:org.apache.catalina.filters.CorsFilter下面有好几个配置的选项,上面没有配置时就采用系统的默认配置。在实际生产环境要根据须要进行配置来提升安全性。好比cors.allowed.origins配置容许访问的源地址,默认为全部,即*。此外,还有cors.allowed.methods,cors.allowed.headers等等。jquery

经过jQuery的ajax进行跨域,这实际上是采用的jsonp的方式来实现的。web

jsonp是英文json with padding的缩写。它容许在服务器端生成script tags至返回至客户端,也就是动态生成javascript标签,经过javascript callback的形式实现数据读取。ajax

html页面端示例代码:apache


//首先要引入jquery的js包
jQuery(document).ready(function(){
$.ajax({ json

      type : "get", //jquey是不支持post方式跨域的 api

      async:false, 跨域

      url : "http://api.taobao.com/apitools/ajax_props.do", //跨域请求的URL

      dataType : "jsonp",

      //传递给请求处理程序,用以得到jsonp回调函数名的参数名(默认为:callback)

      jsonp: "jsoncallback",

     //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名

     jsonpCallback:"success_jsonpCallback",

     //成功获取跨域服务器上的json数据后,会动态执行这个callback函数

     success : function(json){

           alert(json);
     }
   });
});

 

服务器端示例代码,以java为例:

   


public void jsonpTest() throws IOException{

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

//根据html指定的jsonp回调函数的参数名,获取回调函数的名称

//callbackName的值其实就是:success_jsonpCallback

String callbackName = (String)request.getAttribute("jsoncallback");

//简单模拟一个json字符串,实际可以使用google的gson进行转换,次数经过字符串拼接

//{"name":"张三","age":28}

//\是对"号进行转义

String jsonStr = "{\"name\":\"张三\",\"age\":28}";

//最终返回的数据为:success_jsonpCallback({"name":"张三","age":28})

String renderStr = callbackName+"("+jsonStr+")";

response.setContentType("text/plain;charset=UTF-8");

response.getWriter().write(renderStr);
}

jsonp的原理:

 

首先在客户端注册一个callback (如:'jsoncallback'), 而后把callback的名字(如:success_jsonpCallback)传给服务器端对应的处理函数。

服务器先生成须要返回给客户端的 json 数据。而后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数(jsoncallback)的值(success_jsonpCallback) 。

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并将服务器端返回的数据,做为参数,
传入到了客户端预先定义好的 callback 函数(如上例中jquery $.ajax()方法封装的的success: function (json))里。

实际上跨域是经过动态增长script来加载数据,没法直接得到数据,因此须要使用回调函数。

 


$.ajax({
url: url,
data: data,
success: callback,
dataType: json
});

 

getJson跨域获取数据
$.getJSON("http://api.taobao.com/apitools/ajax_props.do&jsoncallback=?",
function (data) {
alert(data);
}
);

 

执行原理:

 

发送请求时须要传一个callback的回调函数名到服务器端,服务器端拿到这个回调函数名,再将返回数据用参数的形式反回到客户端,这样客户端就可以调到。

因此发送请求URL的地址后面必定要上jsoncallback=?这样的参数,jquery会将?号自动替换成自动生成的回调函数的名称。

因此最终的实际请求为:http://api.taobao.com/apitools/ajax_props.do&jsoncallback=jsonp1322444422697

因此和ajax的方式想比较,也就是callback函数一个是自动生成的函数名,一个是手工指定的函数名。

相关文章
相关标签/搜索