CorsFilter
Spring4.2
之前一般自己去实现一个这样的Filter
来处理,4.2
之后框架提供了内置支持。
Reactive的叫
org.springframework.web.cors.reactive.CorsWebFilter
// @since 4.2 public class CorsFilter extends OncePerRequestFilter { private final CorsConfigurationSource configSource; // 默认使用的DefaultCorsProcessor,当然你也可以自己指定 private CorsProcessor processor = new DefaultCorsProcessor(); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 只处理跨域请求 if (CorsUtils.isCorsRequest(request)) { // Spring这里有个bug:因为它并不能保证configSource肯定被初始化了 CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request); if (corsConfiguration != null) { boolean isValid = this.processor.processRequest(corsConfiguration, request, response); // 若处理后返回false,或者该请求本身就是个Options请求,那后面的Filter也不要处理了~~~~~ if (!isValid || CorsUtils.isPreFlightRequest(request)) { return; } } } filterChain.doFilter(request, response); } }
它的工作完全委托给CorsProcessor去处理的。此Filter可以与DelegatingFilterProxy一起使用,以帮助初始化且可以使用Spring容器内的Bean。注意CorsFilter在框架内部默认是木有配置的,若有需要请自行配置~
CorsFilter属于jar包内的过滤器,在没有web.xml环境下如何配置呢?详见下个章节的示例
@CrossOrigin
Spring MVC提供了此注解来帮助你解决CORS跨域问题,比你使用Filter更加的方便,且能实现更加精细化的控制(一般可以和CorsFilter一起来使用,效果更佳)。
Spring Web MVC和Spring WebFlux在RequestMappingHandlerMapping里都是支持此注解的,该注解配置参数的原理可参考CorsConfiguration
// @since 4.2 可使用在类上和方法上 @Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CrossOrigin { // 下面4个属性在5.0后都被此方法所代替 因为此方法默认会被执行 /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */ @Deprecated String[] DEFAULT_ORIGINS = { "*" }; @Deprecated String[] DEFAULT_ALLOWED_HEADERS = { "*" }; @Deprecated boolean DEFAULT_ALLOW_CREDENTIALS = false; @Deprecated long DEFAULT_MAX_AGE = 1800; // 若需要通配,可写* @AliasFor("origins") String[] value() default {}; @AliasFor("value") String[] origins() default {}; String[] allowedHeaders() default {}; String[] exposedHeaders() default {}; RequestMethod[] methods() default {}; String allowCredentials() default ""; long maxAge() default -1; // 负值意味着不生效 By default this is set to {@code 1800} seconds (30 minutes) }
此注解可以标注在Controller
上和方法上,若都有标注将会有combine的效果。
CorsRegistry / CorsRegistration
这两个类是Spring MVC
提供出来便于进行global全局配偶的,它是基于URL pattern
配置的。
public class CorsRegistry { // 保存着全局的配置,每个CorsRegistration就是URL pattern和CorsConfiguration配置 private final List<CorsRegistration> registrations = new ArrayList<>(); // 像上面List添加一个全局配置(和pathPattern绑定) // 它使用的是new CorsRegistration(pathPattern) // 可见使用配置是默认配置:new CorsConfiguration().applyPermitDefaultValues() // 当然它CorsRegistration return给你了,你还可以改(配置)的~~~~ public CorsRegistration addMapping(String pathPattern) { CorsRegistration registration = new CorsRegistration(pathPattern); this.registrations.add(registration); return registration; } // 这个就比较简单了:把当前List专程Map。key就是PathPattern~~~~ protected Map<String, CorsConfiguration> getCorsConfigurations() { Map<String, CorsConfiguration> configs = new LinkedHashMap<>(this.registrations.size()); for (CorsRegistration registration : this.registrations) { configs.put(registration.getPathPattern(), registration.getCorsConfiguration()); } return configs; } }
对于CorsRegistration这个类,它就是持有pathPattern和CorsConfiguration config两个属性,它特特点是提供了allowedMethods/allowedHeaders...等方法,提供钩子方便我们对CorsConfiguration进行配置,源码很简单略。
这两个类虽然简单,但是在@EnableWebMvc里扩展配置时使用得较多,参见下个章节对WebMvcConfigurer扩展使用和配置
相关阅读
CORS跨域资源共享(一):模拟跨域请求以及结果分析,理解同源策略【享学Spring MVC】
CORS跨域资源共享(二):详解Spring MVC对CORS支持的相关类和API【享学Spring MVC】
CORS跨域资源共享(三):@CrossOrigin/CorsFilter处理跨域请求示例,原理分析【享学Spring MVC】
总结
本文内容主要介绍Spring MVC它对CORS支持的那些类,为我们生产是灵活的使用Spring MVC解决CORS问题提供理论基础。下个章节也是本系列的最后一个章节,将具体介绍Spring MVC中对CORS的实践。