jquery 跨域请求数据问题

时间:2021-10-17 22:41:20

昨天参加了一个前端的面试,被问到一个跨域请求数据问题,我们之前一直用的是apicloud的api进行请求的,跨域是被apicloud封装起来的,也就没有注意跨域请求数据的问题。当被问到用jquery跨域请求数据时,我脑中一片空白,所以面试不顺利,也没有通过,今天我差了些资料,看了些文章,解决的jquery跨域请求数据,总接如下:

一、关于ajax跨域的思考

  1、Ajax为什么不能跨域?到底是卡在哪个环节了?(下面项目中具体说,这里先说下结论)。 Ajax其实就是向服务器发送一个GET或POST请求,然后取得服务器响应结果,返回客户端。理论上这是没有任何问题的,然而普通ajax跨域请求,在服务器端不会有任何问题,只是服务端响应数据返回给浏览器的时候,浏览器根据响应头的Access-Control-Allow-Origin字段的值来判断是否有权限获取数据,一般情况下,服务器端如果没有在这个字段做特殊处理的话,跨域是没有权限访问的,所以响应数据被浏览器给拦截了,所以在ajax回调函数里是获取不到数据的(来自园友补充)。所以现在ajax跨域的问题可以转化为数据怎么拿回客户端的问题。

  2、既然不能直接访问第三方站点,我们可以在服务器上面做代理,通过ajax向代理发送请求,代理获得数据后在返回给客户端,当然这是一种解决办法,但是一次请求要从客户端经过代理到第三方站点,然后再原路返回,响应速度是个问题。

  3、我们发现我们可以将一些js、css等文件放在第三方的服务器上面,如CDN等来加快网页的打开速度,这样是没有任何问题的,也就是说web页面可以加载放在任意站点的js、css、图片等资源,不会受到"跨域"的影响。这个时候,我们会想到:既然我们可以调用第三方站点的js,那么如果我们将数据放到第三方站点的js中不就可以将数据带到客户端了吗?

二,现在总结出两种方法进行跨域请求:

①用jquery 的$.getJSON进行跨域请求是可以的,后台只要返回一个json格式的数据就可以了

$.getJSON("http://micro.customer.virtuesoft.cn/home/Paged?pageIndex=1&pageSize=1",function(json){
alert(JSON.stringify(json))
});
注:http://micro.customer.virtuesoft.cn/home/Paged?pageIndex=1&pageSize=1是请求数据的地址,?后面跟的就是传递后台的参数,然后返回的是一个json对象
②jsonp方法请求数据

  JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。其核心思想是利用JS标签里面的跨域特性进行跨域数据访问,在JS标签里面存在的是一个跨域的URL,实际执行的时候通过这个URL获得一段字符串,这段返回的字符串必须是一个合法的JS调用,通过EVAL这个字符串来完成对获得的数据的处理。

  JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

如果只是简单的这样写:

$.ajax({

type:"get",

url:"http://www.abc.com/json.php",

dataType:"jsonp",

jsonp:"callback",

jsonpCallback:"success_jsonpCallback",

success:function(json){

$(".user").html("用户信息:"+json.username+","+json.age+","+json.gender);

},

error:function(){

alert("请求出错!");

}

});

后台数据为:

<?php

$arr = array ('username'=>'jack','age'=>21,'gender'=>'male');

echo json_encode($arr);

?>

在浏览器会报错,错误如下

jquery 跨域请求数据问题

其实这时数据已经拿到了,只是返回的数据格式不对,所以会报错

json.php返回的数据确实是json类型的数据 {“username”:”jack”,”age”:21,”gender”:”male”} ,问题处在哪?

翻看了一下Jquery文档发现jsonp:”callback”, jsonpCallback:”success_jsonpCallback”,传递这两个参数是有原因的,jsonp的返回数据格式应该是: “客户端传递的回调方法名称(json数据)”,将php文件改为:

<?php

$arr = array ('username'=>'jack','age'=>21,'gender'=>'male');

echo $_GET['callback']."(".json_encode($arr).")";

?>

这样就不会报错了,如下

jquery 跨域请求数据问题

可以看到,php文件返回的结果是 success_jsonpCallback({“username”:”jack”,”age”:21,”gender”:”male”}) ,这才是正确的jsonp返回格式,而 success_jsonpCallback这是传递过去的参数 。