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

Ajax跨域的解决方案有2种:CORS、JSONP。下面一一来介绍。 1、CORS CrossOrigin Resource Sharing跨域资源共享。 当前几乎所有的浏览器(Internet Explorer 8+,Firefox 3.5+,Safari...
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属性方法来调用。

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
王凯
王凯

92 篇文章

作家榜 »

  1. admin 651 文章
  2. 粪斗 185 文章
  3. 王凯 92 文章
  4. 廖雪 78 文章
  5. 牟雪峰 12 文章
  6. 李沁雪 9 文章
  7. 全易 2 文章
  8. bngvitmrbj 0 文章