前后端分离之spring跨域Cors解决方案,aop加mvc:cors

2 篇文章 0 订阅
1 篇文章 0 订阅

前后端分离之spring跨域Cors解决方案,aop加mvc:cors


目录

  1. 跨域需求的来源
  2. 前后端分离
  3. spring的拦截器
  4. mvc:cors
  5. aop
  6. 总结

跨域需求由来

  因为浏览器的同源限制策略,现如今很多项目采用前后端分离开发部署。导致前端从服务端获取数
  据时收到阻碍,因此跨域请求数据就尤为重要。恰好java的spring提供了很友好很简单的服务端
  处理Cors请求的方案。网上有很多实现的案例,但是,在本人事件过程中遇到很多不符合需求,
  且非常繁琐的问题。
  这里我汇总了一种简单明了,且同时解决token验证的整体方案。
  若有不足请多指教。

前后端分离

 前后端分离已经是老生常谈了。彻底抛弃.jsp的时代。使得前端趋于软件化,更符合客户端的定义
 前后端只用协同定义数据接口而不用过多考虑彼此的实现。spring为java后端提供了强大的支持
 而前端的工程化,模块化使得前端也可以更高效独立的开发。

spring拦截器

 刚开始,我看到网上有人使用filter配置在web.xml中来处理cors请求,但是filter的request
 对象需要转换成HttpServletRequest来处理,那么我就想为何不直接使用spring提供的拦截器
 接口HandlerInterceptor?代码如下

这里写图片描述
是不是实现很简单?request和response对象可以直接进行操作。这段代码不做过多解释,基本
网上都讲烂了,我们只做比较。
spring配置
这里写图片描述
注释都讲的很清楚,尤其是interceptor的执行顺序这是必须要注意的。
你一定看到里面还有另一个interceptor的实现,那个就是我最初想着既然拦截器实现了跨域
那么能不能一鼓作气吧token验证也做了呢?然后就有了后面的验证拦截器,事实证明很打脸!
这里就要说到,ajax的特殊请求,一般来说post,get这两个常用的请求就是普通请求,那么我们实现跨域之后的token验证,前端必定要将登陆之后返回给前端的token保存起来,并传给服务端进行验证,那么这个token怎么传?最简单的方式就是以参数形式随请求发送给服务器,这样做是不是有点不堪?同时request处理起来也不方便。
这里写图片描述

这张图就是登陆之后返回的数据,其中就包含token,既然token要request接受方便一点那么不如就直接将其放入heard中不是很自然吗?
这里写图片描述
这样实现,当然这只是一种实现方式罢了,我就是图简单。head设置好了,发送吧。接下来的请求头中都会包含token了。那么这个简单的请求变成了复杂请求,复杂请求是什么,自行百度,我只说这个复杂请求会默认向服务端发送一个options请求进行客户端的权限验证,看下图
这里写图片描述
*Access-Control-Allow-Credentials true
Access-Control-Allow-Headers x-token
Access-Control-Allow-Methods POST,GET,OPTIONS,DELETE,PUT
Access-Control-Allow-Origin http://localhost:8081
Access-Control-Max-Age -1*
这部分就是options去服务端干的事情,这也是需服务端处理的东西。其中Max-Age是浏览器缓存这次请求内容的缓存时间,火狐默认是1600秒-1就是不缓存(为了测试);有了缓存之后之后的特殊请求都会省略这次预处理请求options。
说了这么多都是铺垫,因为用interceptor处理跨域和token验证会有一点问题,那么就是options请求根本就到不了interceptor,那么就导致options的请求直接跳过了响应头的设置,也就是说客户端的验证请求options什么也没做就返回了,导致跨域失败。很痛苦啊,好不容易找到一个简单的还有问题?没关系继续。。。。

mvc:cors

这个就牛逼了,一步配置就把CORSInterceptor给取代了,而且options请求预处理可以顺利完成。这里写图片描述
各个参数按照需求配置就可以了,我的token就是x-token头,被允许就可以。
接着又出现新问题,配置了mvc:cors之后的options请求是会到达interceptor拦截器的,这和之前没配置的时候是不一样了(spring的版本问题,之前用的4.0.5,options请求是被禁用的,在handler之前被处理返回了,需要在web.xml中打开这里写图片描述,4.2之后options又是默认打开这就有点懵逼了)。那么options请求到达token验证的拦截器的时候会怎么样呢?
这里写图片描述
看日志就知道options被Handler接管了,那么因为options是浏览器默认行为所有我设置的请求同它并不会携带,就会导致token验证失败,呵呵哒。。。
这里写图片描述
同时浏览器也会拒绝跨域请求,所以呢,用Handler拦截器做token验证就不可取了。

aop

拦截器不行咱就上刀,切一下Controller,在每个Handler执行之前,这样就可以避开OPTION请求了。
这里写图片描述
matchToken方法就是验证用户token的方法,和拦截器的实现基本没变,只是它不用返回任何值,如果验证不通过直接抛出RuntimeException就可以了,通过spring的异常统一处理方法就可以处理掉。
aop的功能还有很多,你可以看到,处理用户token的外层方法其实是一个统一输出Controller日志的方法。

总结

至此,整个实现过程已经阐述完毕,借助spring的强大功能,完成了整个框架的构建,这里我只说了一部分跨域和token验证的内容,也是比较核心的内容。
完全结合spring不使用Filter,既然封装了就不要暴露底层。spring的interceptor是在filter之后执行的所以使用handlerInterceptor处理Cors还是会出现一定问题。mvc:cors完美解决,用户token验证,那么就越靠后越好,aop可以直接切到Controller每个方法执行之前验证,避免浏览器验证请求被干扰。
其中配到配置mvc:cors和不配置它对HandlerInterceptor的影响,需要再做研究,如果有哪位大神对springMvc源码有深入研究还请指教。指点迷津。。。

          完!
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值