vue+springboot实现项目的CORS跨域请求
跨域资源共享cors(cross-origin resource sharing),是w3c的一个标准,允许浏览器向跨源的服务器发起xmlhttprequest请求,克服ajax请求只能同源使用的限制。关于cors的详细解读,可参考阮一峰大神的博客:跨域资源共享cors详解。本文为通过一个小demo对该博客中分析内容的一些验证。
1.springboot+vue项目的构建和启动
细节不在此赘述,任何简单的springboot项目就可以,而前端vue项目只需用axios发ajax请求即可。
我的demo里填写用户名和密码,然后点击登录按钮向后台发起登录请求,js代码如下:
methods:{ login:function() { //var userparams = this.$qs.stringify(this.user); /* var userparams = json.stringify(this.user);*/ this.$axios.post("http://localhost:8080/login",this.user).then(res=>{ alert(res.data); }); } }
后台控制器部分,对登录请求的处理:
/*cors设置方法1:@crossorigin(origins = "http://localhost:8081", maxage = 3600)*/ @requestmapping(value="/login",method = requestmethod.post, produces = "application/json;charset=utf-8" ) @responsebody public string userlogin(@requestbody jsonobject user) { /*string name=request.getparameter("name"); string password=request.getparameter("password");*/ system.out.println("name: " + user.get("name")); system.out.println("password: " + user.get("password")); string name = (string) user.get("name"); string password = (string) user.get("password"); if(name.equals("zsz") && password.equals("888888")){ return "login success!"; }else{ return "login failed"; } }
后台以8080端口启动,前台以8081启动,此时无法跨域,浏览器控制台会报错:
2.springboot设置cors
此处主要有两种方法(但是貌似有其他博客还有更多种),在springboot中实现都比较简单(反正springboot好像就是各种省事各种简单)。
方法1:
@crossorigin(origins = "http://localhost:8081", maxage = 3600)
直接在控制器方法前注解,设置可以跨域的源ip和端口,以及预检有效期maxage等参数。
方法2:
编写配置类,配置全局的cors设置。
@configuration public class mycorsconfig { @bean public webmvcconfigurer corsconfigurer(){ return new webmvcconfigureradapter() { @override public void addcorsmappings(corsregistry registry) { // 限制了路径和域名的访问 /*registry.addmapping("/api*").allowedorigins("http://localhost:8081");*/ registry.addmapping("/**") .allowedorigins(all) .allowedmethods(all) .allowedheaders(all) .allowcredentials(true); } }; } }
如果路径配置成以上的 /**则对所有源路径均接受跨域访问,当然也可以配置更详细的路径。
这样可以成功访问后台,浏览器中可以看到http请求和响应的结果如下图:
3.cors非简单请求预检请求的抓包验证
根据阮一峰大神的博客所述,cors简单请求只发送一次请求,服务器设置支持cors则会在响应内容中添加acess-control-allow-origin等字段,否则不添加,浏览器知道出错,从而抛出异常;cors非简单请求时,会先进行一次预检(preflight)请求,浏览器根据响应内容进行正式的xmlhttprequest请求。
在我的demo中,我通过将http请求的 content-type 设置为application/json进行非简单请求。此处要说明一下,axios默认情况下发送请求的格式是application/json而不是我之前用jquery发送ajax请求的application/x-www-form-urlencoded, 而我之前用的另一种方法构造查询字符串,最终发送请求的content-type会变为application/x-www-form-urlencoded。
var userparams = this.$qs.stringify(this.user)
前台请求代码如本文第一节中所示,在axios请求中直接传入user对象即可。在后端不设置cors的时候,控制器信息为:
协议内容为:
而设置了cors,预检请求结果为:
请求成功,并且在响应头中添加了各种字段。
再次发起xhr请求后,结果为:
以上实验验证证明了两种cors请求的过程正如预期。希望对大家的学习有所帮助,也希望大家多多支持。