查看原文
其他

学会Spring Mvc 跨域你只需要看完这一篇

码农小胖哥 码农小胖哥 2019-09-11

同源策略


现在普遍前后端分离,前端 http://ip:port/context 后端http://ip:anotherport/anothercontext ,然后你发现浏览器提示跨域了。或者你是前端或者后端。你们ip不一样,端口一样 ,前端调用后端接口依然提示跨域了。是不是很郁闷?这个跨域是什么玩意儿呢?简单来说如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的



这张图 会让你明白什么时候是同源,什么时候不同源,不同源如果要进行交互就需要跨域。至于为什么要限制,浏览器策略说是为了安全限制,具体原因可以去MDN 了解。本文不讨论。我们只讨论如何跨域。


跨域的方式

  • JSONP  在HTML标签里,一些标签比如script、img这样的获取资源的src标签是没有跨域限制的,利用这一点。但是现在都9102年了,这种基本不使用了,除非老项目。而且获取资源只能使用GET请求。

  • 空的iframe加上 form表单     iframe 也是带src 的 但是 iframe 中可以放一个form ,form当然可以指定为POST,用后即焚。解决了JSONP不能使用POST的问题。但是也很别扭。

  • CORS   CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。看名字就知道这是处理跨域问题的标准做法。CORS有两种请求:

                   

a.简单请求


(1) 请求方法是以下三种方法之一:

  • HEAD

  • GET

  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept

  • Accept-Language

  • Content-Language

  • Last-Event-ID

  • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-       data、 text/plain


b.非简单请求


非简单请求会发出一次预检测请求,返回码是204,预检测通过才会真正发出请求,这才返回200。这里通过前端发请求的时候增加一个额外的headers来触发非简单请求。额外的请求头参数有


  • Access-Control-Allow-Origin  标识允许哪个域的请求。当然,如果服务器不通过,根本没有这个字段,接着触发XHR的onerror,再接着你就看到浏览器的提示xxx的服务器没有响应Access-Control-Allow-Origin字段。设置*是最简单的,出于安全考虑,肯定不会这么干,而且,如果是*的话,游览器将不会发送cookies,即使你的XHR设置了withCredentials,网上很多教程这么干。

  • Access-Control-Allow-Credentials     设置布尔值,表示XHR是否接收cookies和发送cookies,也就是说如果该值是false,响应头的Set-Cookie,浏览器也不会理,并且即使有目标站点的cookies,浏览器也不会发送。

  • Access-Control-Request-Method  跨域请求满足服务器要求的所有请求方式,GET、POST、PUT等

  • Access-Control-Request-Headers  跨域请求的自定义请求头字段,不限定本次请求一次性告诉服务端。



spring mvc中的cors跨域


以上就是跨域方式的简单介绍,这里我们着重介绍cors这种现代的操作方式,以及在spring mvc中如何设置cors。

  • 局部跨域


使用@CrossOrigin注解   这种最为简单。该注解的属性值跟上面的非简单请求需要的的header参数一一对应,也可以不设置。使用起来也最简单,就像下面的操作:



上面是方法级别的控制粒度。在上面的示例中,CORS仅对canCors()方法启用。如果该控制器下所有的方法都要跨域,而且我们也可以指定一些参数。



这样CorsApi下所有的方法都将支持从 https://api.com 的跨域操作。使用@CrossOrigin的方式虽然简单。但是我们不可能不厌其烦的进行这种操作。如果我们能指定一些通配符方式的来指定那些操作可以cors就好了,当然有下面我们来看看全局配置。


  • 全局跨域配置


WebMvcConfigurer  是我们的老朋友了,什么过滤器,格式化器,各种视图转换器,各种处理器都是它来注册的,就是一个Spring mvc 的配置中心。通过Ant风格的路径和Cors参数配置我们就可以全局来使用了不再需要注解支持。这种是javaConfig的玩法。如果是老式SSM 那种xml方式该这样玩



简单原理流程


通过 注解或者全局配置的CORS请求会被自动分发到各种已经注册的HandlerMappings(spring mvc 概念),然后由跨域处理器 CorsProcessor 接口(默认实现为DefaultCorsProcessor)来处理CORS预检请求(注意前面非简单的CORS请求介绍),然后拦截器CorsFilter拦截实际的具体请求,添加相关的CORS  Headers (例如Access-Control-Allow-Origin),从而实现跨域请求。


总结

我们从跨域的概念到多种cors跨域方式的简单介绍,后面重点介绍了springmvc中CORS的注解方式,全局方式(包括javaConfig方式和xml方式),也讲述了简单的原理流程。相信对于目前前后端分离开发方式还是非常有指导意义的。

长|按|扫|码|关|注



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存