Ajax跨域的解决方案——CORS、JSONP

Ajax跨域的解决方案有2种:CORS、JSONP。下面一一来介绍。

 

1、CORS

 

CrossOrigin Resource Sharing跨域资源共享。

 

当前几乎所有的浏览器(Internet Explorer 8+,Firefox 3.5+,Safari 4+和Chrome)都可通过名为跨域资源共享(Cross-Origin Resource Sharing)的协议支持ajax跨域调用。 

 

对一个简单的请求,没有自定义头部,要么使用GET,要么使用POST,它的主体是text/plain,请求用一个名叫Origin的额外的头部发送。Origin头部包含请求页面的头部(协议,域名,端口),这样服务器可以很容易的决定它是否应该提供响应。

 

服务器端:JSP页面中设置response.addHeader("Access-Control-Allow-Origin", "http://www.yoursite.com:8080")。

 

在请求信息中,浏览器使用 Origin 这个 HTTP 头来标识该请求来自于 http://www.yoursite.com:8080(发出跨区请求的url)。

 

在返回的响应信息中,使用 Access-Control-Allow-Origin 头来控制哪些域名的脚本可以访问该资源。

 

如果设置 Access-Control-Allow-Origin为*,则允许所有域名的脚本访问该资源。如果有多个,则只需要使用逗号分隔开即可。

 

 

 

2、JSONP

 

JSONP是JSON with Padding的略称,是一个非官方的协议,允许在服务器端集成Script tags返回至客户端,通过JavaScript callback的形式实现跨域访问。

 

JSONP比JSON外面有多了一层,callback()。也就是说,在服务器端需要先将查询结果转换成JSON格式,然后用参数callback在JSON外面再套一层,就变成了JSONP。

 

JSON格式:

 

{
"message":"获取成功",
"state":"1"
}

JSONP格式:

 

callback({
"message":"获取成功",
  "state":"1"
})

(1)JavaScript与JSONP

 

JSONP的简单实现模式:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

 

http://www.msnova.net/a.html

 

<script type="text/javascript">
function callback(data) {
alert(data.message);
}
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("http://blogs.msnova.net/b.js");
}
</script>

http://blogs.msnova.net/b.js

 

callback({message:"success"}); 

说明:

 

① 动态创建script:addScriptTag方法中的document.body.appendChild(script)实现script标签被添加到body里,由于我们JS代码是在head标签中,执行到document.body.appendChild(script)时document.body可能还没有初始化完毕,所以通过window.onload方法确保页面加载完毕再添加script标签。

 

② 实际上,<script>标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行,因此,以上实例并不能算是一个真正的JSONP跨域服务。下面是真正的JSONP跨域服务:

 

http://www.msnova.net/a.html

 

<script type="text/javascript">
function result(data) {
alert("Hello " + data.student[0].name);
}
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("http://blogs.msnova.net/dataProcessor?city=Beijing&callback=result");
}
</script>

服务器端http://blogs.msnova.net/dataProcessor会将查询结果转换成JSON格式,然后用参数callback在JSON外面再套一层变成JSONP作为响应返回,此处涉及到后台代码,不写出。

 

 

 

(2)jQuery与JSONP

 

jQuery框架也支持JSONP,可以使用$.getJSON(url,[data],[callback])方法和$.ajax()方法。

 

① $.getJSON方法:

 

<script type="text/javascript">
$.getJSON("http://blogs.msnova.net/dataProcessor?callback=?",function(data){
alert("Hello " + data.student[0].name);
});
</script>

注意:在url的后面必须添加一个callback参数,这样getJSON()方法才知道是用JSONP方式,callback后面的问号是内部自动生成的一个回调函数名。

 

 

② $.ajax()方法:

 

a.  jsonp参数:

 

使用$.ajax形式可以不在url的后面添加一个callback参数,但此时需要指定jsonp参数。jsonp: “callback”代表的是服务端通过String callback = request.getParameter("callback") 接收客户端回调函数名的参数名,ajax请求中jsonp参数的默认值就是callback,也可以自己随便定义。

 

$.ajax({
   url:"http://blogs.msnova.net/dataProcessor",   
   dataType:"jsonp",
  jsonp:"callback",
 success:function(data){
  alert("Hello " + data.student[0].name);
 }
});

等价于:

 

$.ajax({
   url:"http://blogs.msnova.net/dataProcessor?callback=?",   
   dataType:"jsonp",
 success:function(data){
  alert("Hello " + data.student[0].name);
 }
});

b.  jsonpCallback参数:

 

jsonpCallback: “callbackHandler”代表的是服务端调用结束后的本地回调函数名,比如jsonp: “callback”中的客户端回调函数名,jsonpCallback的参数值也可以自己随便定义,也可以不给jsonpCallback参数,其实jQuery会自动生成一个函数和函数名,远程服务调用成功后,既执行了success这个回调函数,也执行自己定义的jsonpCallback指定的回调函数,所以完全可以使用jQuery生成的回调函数,在调用结束后在success回调中做相应的处理即可。

 

$.ajax({
   url:"http://blogs.msnova.net/dataProcessor?callback=?",   
   dataType:"jsonp",
  jsonpCallback:"result",
 success:function(data){
  alert("Hello " + data.student[0].name);
 }
});

等价于:

 

$.ajax({
   url:"http://blogs.msnova.net/dataProcessor",   
   dataType:"jsonp",
jsonp:"callback",
  jsonpCallback:"result",
 success:function(data){
  alert("Hello " + data.student[0].name);
 }
});

此处并没有定义result函数,也运行成功了。这是jQuery的功劳,jQuery在处理jsonp类型的ajax时,会自动生成回调函数并把数据取出来供success属性方法来调用。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.duanlonglong.com/qdjy/473.html