Ajax跨域二(在浏览器、jsonp方面解决跨域)
一、在浏览器方面解决跨域:
浏览器的跨域设置,在浏览器的属性设置页面的目标输入框里加上--disable-web-security,这样就可以让浏览器支持跨域了。
在浏览器的安装目录启动终端,输入禁止浏览器做跨域检查的校验参数,新启一个浏览器。
命令参数(参数视具体情况而定):chrome --disable-web-security --user-data-dir=g:\temp3。

二:JSONP解决跨域:
对于发出XHR请求,解决方案是JSONP;
JSONP如果解决跨域思路:利用script标签,请求可以跨域来解决跨域问题。
办法:使用ajax发送请求,dataType为JSONP,即可解决跨域问题。但这需要接口返回一个script标签;如果返回其他格式的数据,浏览器将会把它当成是js代码解析,所以将会报错。(注意:此种情况也是需要修改服务器后台代码的)
前端测试代码:
// 测试方法 it("jsonp请求", function(done) { // 服务器返回的结果 var result; //初始化是undifined $.ajax({ url:base+"/get1", dataType:"jsonp", //关键数据类型:jsonp cache:true, //加入缓存 success:function(json){ result = json; } }); // 由于是异步请求,需要使用setTimeout来校验 setTimeout(function() { expect(result).toEqual({ "data" : "get1 ok" }); // 校验完成,通知jasmine框架 done(); }, 100); });
直接调用会报跨域问题,如下:


可以看出jsonp在没有加后台代码情况下是会报错的,解决办法:添加一个后台代码(添加一个切面)
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice; @ControllerAdvice public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice{ public JsonpAdvice(){ super("callback"); //作用,前端调用的JSONP格式的时候,需要加上callback参数 } }
后台代码修改为JSONP后,在浏览器看到的区别:
- 前端发出去的请求类型在浏览器可以看到是script类型的,浏览器是不会校验的。普通的ajax请求是xhr类型的。
- 返回的类型不同:普通的ajax请求content-type是json,而jsonp的请求content-type是js脚本。
- url不同,jsonp的url后面有callback...一串的参数。
界面如下所示(加入后台代码之后,使用jsonp方式发送已不报错):

jsonp是一种非正式传输协议,是前后台约定的协议,而不是官方协议。
jsonp的实现原理是:
前后台约定带有“callback”这个参数的请求就是jsonp请求,前台发出去的请求加了“callback”参数,当后台发现请求中带“callback”时,后台就知道这是一个jsonp请求,就会把返回的数据由json变成JS代码返回,JS代码内容就是一个函数的调用,函数名是“callback”参数的值,而原来需要返回的json对象数据在这里作为参数传递返回。

补充说明:
(1)当把地址栏的“callback”改为“callback2”,点击浏览器控制台下的请求地址可以看到返回结果变成了json。原因是前后台约定的jsonp参数是“callback”,如果要正确返回jsonp的js代码,那么就需要后台参数改为“callback2”,前台的ajax请求里加jsonp:"callback2"参数设置。
(2)在浏览器查看jsonp请求里除了callback参数外,还有一个名为下划线“_”的参数,值为一串随机数。此参数作用是防止请求被缓存。如果你的请求可以被缓存的话,可以在请求里使用cache:true。
JSONP的弊端:
(1)服务器需要改动代码支持-如果调用的接口不是我们自己的,那么改动就很麻烦
(2)只支持GET方法,JSONP是通过动态创建一个script发送请求的,而script只支持GET方法
(3)发送的不是XHR请求,XHR有许多新的特性,如异步、各种事件等,JSONP则没有。
解决方案:
被调用方解决:是基于支持跨域的解决思路,基于http协议关于跨域方面的一些规定,在响应头里加允许调用字段,跨域请求是直接从浏览器发送过去的;
(1)服务器端实现;(2)NGINX配置;(3)APACHE配置。
调用方解决:是基于隐藏跨域的解决思路,跨域请求不会直接从浏览器发到被调用方,而是从中间的http服务器转发过去的。
举例子:调用方为a.com,被调用方为b.com。
补充:跨域请求都是先请求后判断,就是先请求后台服务器返回内容,然后判断请求头是否存在跨域问题。
理论参考:http://www.cnblogs.com/lojun/articles/9426409.html
代码下载地址:https://download.csdn.net/download/lowi313804/10584874

浙公网安备 33010602011771号