SpringMvc办理跨域问题的源码汇总。

打印 上一主题 下一主题

主题 1003|帖子 1003|积分 3011

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
看本文章前,需相识跨域的缘由。
其次,相识RequestMapping的底子原理
末了我们来剖析SpringMvc是如那边理跨域问题的。
                                    跨域信息配置

SpringMvc分为全局级别和局部级别两种,全局级别就是任何跨域请求都起作用。
                                          全局级别

全局级别就是在配置HandlerMapping时,从源码分析可知,AbstractHandlerMapping是requestMapping的第一子类,其内部拥有属性globalCorsConfigSource,这个属性对应的对象是一个实现了org.springframework.web.cors.CorsConfigurationSource的对象,通过袒露org.springframework.web.servlet.handler.AbstractHandlerMapping#setCorsConfigurations方法,可以直接向globalCorsConfigSource注入url与跨域配置信息。至于该方法如何调用,则是在Springboot里有所体现。

                                          局部级别

而局部级别的,就是针对request的url对应的特定handler起作用。从RequestMapping的查找我们可以得知,springmvc在获取handler的过程中,有两种剖析方式,一种是对象级别的,一种是方法级别的。
                                                针对对象级别的

SpringMvc提供了org.springframework.web.cors.CorsConfigurationSource接口,也就是说,如果你的handler实现了org.springframework.web.cors.CorsConfigurationSource,那么当有跨域出现的请求时,会优先利用CorsConfigurationSource的实现来实现。
                                               针对方法级别的

优先利用在方法上注解的org.springframework.web.bind.annotation.CrossOrigin,其次利用所属bean上注解的org.springframework.web.bind.annotation.CrossOrigin。它们会将这个注解信息剖析成CorsConfigurationSource的子类。

                                    如那边理跨域

首先,根据欣赏器跨域规则我们可以知道,对于跨域资源,欣赏器会有两种行为。
一种行为是,如果是一个简单的Get跨域请求,欣赏器将直接发起请求。
另外一种行为是,如果是一个利用 PUT 或 DELETE 方法的请求,欣赏器会发送一个预检请求,所谓的预检请求,指的就是发送一个请求方法为OPTIONS的请求。
针对这两种行为,SpringMvc有不同的处理方式。
                                             OPTIONS请求方法

针对OPTION的跨域请求方法,springMvc底层会默认匹配一个PreFlightHandler的handler,这个handler作用也很简单,就是查找上面的CorsConfigurationSource,获取这个url匹配的跨域配置CorsConfiguration,并且查看做如下匹配
1.请求的Request的Origin头的值,是否与CorsConfiguration里的allowedOrigins里匹配,匹配则放行。
2.再次查抄Access-Control-Request-Method头的值,是否与CorsConfiguration里allowedMethods是否匹配,匹配则放行。
3.再次查抄Access-Control-Request-Headers头的值,是否与CorsConfiguration里allowedHeaders是否匹配,匹配则放行。
如果上面任意一步无法做到匹配,就会直接返回一个Response,状态码为403,而值的信息Invalid CORS request。
如果以上都通过了,则直接会设置如下的相应头:
  1. Access-Control-Allow-Origin:即Request请求里的Origin头
复制代码
  1. Access-Control-Allow-Methods:即Request里的Access-Control-Request-Method对应的值,且该值必须被跨域允许的,比如,传了GET、POST,但是跨域配置里,即CorsConfiguration的allowedMethods为GET,则该值就会是GET
复制代码
  1. Access-Control-Allow-Headers:即Request里的Access-Control-Request-Headers对应的值,且该值必须被跨域允许的,比如,传了COOKIE、TOKEN等,但是跨域配置里,即CorsConfiguration的allowedHeaders为TOKEN,则该值就会是TOKEN
复制代码
  1. Access-Control-Expose-Headers:即根据跨域配置里,即CorsConfiguration的exposedHeaders的值,这个值的作用是什么呢?那就是告诉浏览器,你接到这个相应的时候,可以暴露哪些头信息,比如自定义了一个Token头,但是如果你不指定的话,浏览器是不会展示这个头给用户的,即便,你在响应里设置了这个头。
复制代码
  1. Access-Control-Allow-Credentials:该值是告诉浏览器,是否允许发送敏感信息,这些敏感信息包含cookie、TLS 客户端证书,或包含用户名和密码的认证标头等。为true则是允许。
复制代码
Access-Control-Max-Age:用于指定预检请求(preflight request)的结果可以缓存多长时间,以减少欣赏器发送预检请求的次数,从而提升跨域请求的性能。
                                            直接请求方法

对于非预检请求,springMvc会为这个handler天生一个HandlerInterceptor,即org.springframework.web.servlet.handler.AbstractHandlerMapping.CorsInterceptor。
这个拦截器的org.springframework.web.cors.DefaultCorsProcessor#processRequest里对请求是否跨域进行处理。
1.请求的Request的Origin头的值,是否与CorsConfiguration里的allowedOrigins里匹配,匹配则放行。
2.再次查抄Access-Control-Request-Method头的值,是否与CorsConfiguration里allowedMethods是否匹配,匹配则放行。
如果以上都通过了,则直接会设置如下的相应头:
  1. Access-Control-Allow-Origin:即Request请求里的Origin头
复制代码
  1. Access-Control-Expose-Headers:即根据跨域配置里,即CorsConfiguration的exposedHeaders的值,这个值的作用是什么呢?那就是告诉浏览器,你接到这个相应的时候,可以暴露哪些头信息,比如自定义了一个Token头,但是如果你不指定的话,浏览器是不会展示这个头给用户的,即便,你在响应里设置了这个头。
复制代码
  1. Access-Control-Allow-Credentials:该值是告诉浏览器,是否允许发送敏感信息,这些敏感信息包含cookie、TLS 客户端证书,或包含用户名和密码的认证标头等。为true则是允许。
复制代码
如果以上有任意匹配不通过,则直接通过拦截器返回CorsInterceptor返回false,即不再继续处理请求。

                                                 CorsConfiguration

从上面我们可以知道,无论你用那种方法,跨域的配置信息始终存放在org.springframework.web.cors.CorsConfigurationSource的子类中,而这个类SpringMvc默认提供的实现是org.springframework.web.cors.UrlBasedCorsConfigurationSource。org.springframework.web.cors.UrlBasedCorsConfigurationSource则黑白常简单,就是根据url查找到对应的CorsConfiguration对象。
                                   


  1. CorsConfiguration内部存储着如下信息:
复制代码
  1. allowedOrigins:即它指定了跨域Request的Access-Control-Allow-Origin的头信息,如果这个属性里不包含Access-Control-Allow-Origin,就代表跨域不允许。
复制代码
  1. allowedMethods:即它指定了跨域Request的Access-Control-Request-Headers的头信息,如果这个属性里不包含Access-Control-Request-Headers,就代表跨域不允许。
复制代码
  1. allowedHeaders:即它指定了跨域Request的Access-Control-Request-Method的头信息,如果这个属性里不包含Access-Control-Request-Method,就代表跨域不允许
复制代码
exposedHeaders:Access-Control-Expose-Headers
[code][/code]




                                                      


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南七星之家

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表