springboot后端跨域addCorsMappings与拦截器冲突导致跨域失效
-
失效原因:
请求处理的顺序问题,请求打到后端时,是先被拦截器拦截处理的,也就是我们配置的addCrosMappings并没有起到作用,请求直接被拦截器拦截了,而由于此时请求还没有配置跨域信息,所以就出现了跨域问题
//预检请求处理时是预检请求则生成个预检执行器PreFlightHandler,
//否则生成一个跨域拦截器加入拦截器链中,最终再doDispatch函数处执行,而因为拦截器是顺序执行的,如果前面执行失败异常返回后,后面的则不再执行。protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request, HandlerExecutionChain chain, @Nullable CorsConfiguration config) { if (CorsUtils.isPreFlightRequest(request)) { HandlerInterceptor[] interceptors = chain.getInterceptors(); chain = new HandlerExecutionChain(new AbstractHandlerMapping.PreFlightHandler(config), interceptors); } else { chain.addInterceptor(0, new AbstractHandlerMapping.CorsInterceptor(config)); } return chain; }
2:解决方案:
将跨域配置处理置于过滤器处理:
过滤器与拦截器的区别:
过滤器:Filter是依赖于Servlet容器,Filter的执行由Servlet容器的init方法回调完成,适用于所有请求,Filter的生命周期由Servlet容器管理。
拦截器:拦截器是通过aop实现的,只适用于controller,可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例.
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
//1.添加CORS配置信息
CorsConfiguration config = new CorsConfiguration();
//放行哪些原始域
config.addAllowedOrigin("");
//是否发送Cookie信息
config.setAllowCredentials(true);
//放行哪些原始域(请求方式)
config.addAllowedMethod("");
//放行哪些原始域(头部信息)
config.addAllowedHeader("*");
//2.添加映射路径
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
//3.返回新的CorsFilter.
return new CorsFilter(configSource);
}
}