Spring的跨域的几个方案
目录
- 1.@CrossOrigin
- 2.addCorsMappings
- 3.CorsFIlter
1.@CrossOrigin
@CrossOrigin
可以添加到方法上,也可以添加到Controller
上AbstractHandlerMethodMapping的内部类MappingRegistry的register:
public void register(T mapping, Object handler, Method method) {// Assert that the handler method is not a suspending one.if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {Class>[] parameterTypes = method.getParameterTypes(); if ((parameterTypes.length > 0) && "kotlin.coroutines.Continuation".equals(parameterTypes[parameterTypes.length - 1].getName())) {throw new IllegalStateException("Unsupported suspending handler method detected: " + method); }}this.readWriteLock.writeLock().lock(); try {HandlerMethod handlerMethod = createHandlerMethod(handler, method); validateMethodMapping(handlerMethod, mapping); this.mappingLookup.put(mapping, handlerMethod); List directUrls = getDirectUrls(mapping); for (String url : directUrls) {this.urlLookup.add(url, mapping); }String name = null; if (getNamingStrategy() != null) {name = getNamingStrategy().getName(handlerMethod, mapping); addMappingName(name, handlerMethod); }CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping); if (corsConfig != null) {this.corsLookup.put(handlerMethod, corsConfig); }this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name)); }finally {this.readWriteLock.writeLock().unlock(); }}
@CrossOrigin
注解在AbstractHandlerMethodMapping
的内部类MappingRegistry
的register方法中完成解析,@CrossOrigin注解中的内容会被解析成一个配置对象CorsConfiguration- 将
@CrossOrigin
所标记的请求方法对象HandlerMethod
和CorsConfiguration
一一对应存入corsLookup的map集合中 - 当请求到达
DispatcherServlet
的doDispatch方法之后,调用AbstractHandlerMapping
的getHandler方法获取执行链HandlerExecutionChain时,会从map中获取CorsConfiguration对象 - 根据获取到的
CorsConfiguration
对象构建一个CorsInterceptor拦截器 - 在
CorsInterceptor
拦截器中触发对CorsProcessor
的processRequest方法调用,跨域请求的校验工作将在该方法中完成。
2.addCorsMappings
@CrossOrigin
是添加在不同的Controller
中 全局配置@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedMethods("*").allowedOrigins("*").allowedHeaders("*").allowCredentials(false).exposedHeaders("").maxAge(3600); }}
【Spring的跨域的几个方案】全局配置和
@CrossOrigin
注解相同,都是在CorsInterceptor
拦截器中触发对CorsProcessor的processRequest方法调用,最终在该方法中完成跨域请求的校验工作registry.addMapping(“/**”)
方法中配置了一个CorsRegistration对象,该对象中包含了一个路径拦截规则,同时CorsRegistration还包含了一个CorsConfiguration配置对象,该对象用来保存这里跨域相关的配置。- 在
WebMvcConfigurationSupport
的requestMappingHandlerMapping
方法中触发了addCorsMappings方法执行,将获取到的CorsRegistration对象重新组装成一个UrlBasedCorsConfigurationSource对象,该对象保存了拦截规则和CorsConfiguration对象的映射关系。 - 将新建的
UrlBasedCorsConfigurationSource
对象赋值给AbstractHandlerMapping的corsConfigurationSource属性 - 当请求到达时的处理方法和
@CrossOrigin
注解处理流程一样,在AbstractHandlerMapping的getHandler方法处理,从corsConfigurationSource
中获取CorsConfiguration配置对象,而@CrossOrigin从map中获取CorsConfiguration对象。如果两处都可以获取到CorsConfiguration对象,则获取到的对象属性值进行合并。 - 根据获取到的
CorsConfiguration
对象构造CorsInterceptor拦截器 - 在
CorsInterceptor
拦截器中触发对CorsProcessor的processRequest方法调用,跨域请求的校验工作将在该方法中完成。
这里的跨域校验是通过DispatcherServlet中的方法触发的,DispatcherServlet在Filter之后执行
3.CorsFIlter
@Configurationpublic class WebMvcConfig {@BeanFilterRegistrationBeancorsFilter() {FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowedHeaders(Arrays.asList("*")); corsConfiguration.setAllowedMethods(Arrays.asList("*")); corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:8081")); corsConfiguration.setMaxAge(3600L); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfiguration); registrationBean.setFilter(new CorsFilter(source)); registrationBean.setOrder(-1); return registrationBean; }}
- 手动创建
CorsConfiguration
对象 - 创建
UrlBasedCorsConfigurationSource
对象,将过滤器的拦截规则和CorsConfiguration
对象之间的映射关系由UrlBasedCorsConfigurationSource
中的corsConfiguration
变量保存起来。 - 最后创建
CorsFilter
设置优先级
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request); boolean isValid = this.processor.processRequest(corsConfiguration, request, response); if (isValid && !CorsUtils.isPreFlightRequest(request)) {filterChain.doFilter(request, response); }}
触发对
CorsProcessor
的processRequest
方法调用,跨域请求的校验工作将在该方法中完成到此这篇关于Spring的跨域的几个方案的文章就介绍到这了,更多相关Spring的跨域方案内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- HttpMessageConverter报文信息转换器的深入讲解
- Python的数据结构与算法之队列详解
- js实现简单的抽奖系统
- .NET中常见的加解密算法详解
- 使用Docker镜像构建Go应用的实现方法
- Python的ini配置文件你了解吗
- pytorch中的广播语义
- ECMAScript|js中对象和数组的浅拷贝与深拷贝(ES6、前端面试常用)
- 面试|前端面试——深拷贝与浅拷贝的区别
- 前端的深拷贝和浅拷贝_前端面试-深拷贝和浅拷贝