Spring的跨域的幾個方案
1.@CrossOrigin
@CrossOrigin
可以添加到方法上,也可以添加到Controller
上
AbstractHandlerMethodMapping的內(nèi)部類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<String> 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
的內(nèi)部類MappingRegistry
的register方法中完成解析,@CrossOrigin注解中的內(nèi)容會被解析成一個配置對象CorsConfiguration- 將
@CrossOrigin
所標(biāo)記的請求方法對象HandlerMethod
和CorsConfiguration
一一對應(yīng)存入corsLookup的map集合中 - 當(dāng)請求到達(dá)
DispatcherServlet
的doDispatch方法之后,調(diào)用AbstractHandlerMapping
的getHandler方法獲取執(zhí)行鏈HandlerExecutionChain時,會從map中獲取CorsConfiguration對象 - 根據(jù)獲取到的
CorsConfiguration
對象構(gòu)建一個CorsInterceptor攔截器 - 在
CorsInterceptor
攔截器中觸發(fā)對CorsProcessor
的processRequest方法調(diào)用,跨域請求的校驗工作將在該方法中完成。
2.addCorsMappings
@CrossOrigin
是添加在不同的Controller
中 全局配置
@Configuration public class WebMvcConfig implements WebMvcConfigurer { ? ? @Override ? ? public void addCorsMappings(CorsRegistry registry) { ? ? ? ? registry.addMapping("/**") ? ? ? ? ? ? ? ? .allowedMethods("*") ? ? ? ? ? ? ? ? .allowedOrigins("*") ? ? ? ? ? ? ? ? .allowedHeaders("*") ? ? ? ? ? ? ? ? .allowCredentials(false) ? ? ? ? ? ? ? ? .exposedHeaders("") ? ? ? ? ? ? ? ? .maxAge(3600); ? ? } }
全局配置和@CrossOrigin
注解相同,都是在CorsInterceptor
攔截器中觸發(fā)對CorsProcessor的processRequest方法調(diào)用,最終在該方法中完成跨域請求的校驗工作
registry.addMapping(“/**”)
方法中配置了一個CorsRegistration對象,該對象中包含了一個路徑攔截規(guī)則,同時CorsRegistration還包含了一個CorsConfiguration配置對象,該對象用來保存這里跨域相關(guān)的配置。- 在
WebMvcConfigurationSupport
的requestMappingHandlerMapping
方法中觸發(fā)了addCorsMappings方法執(zhí)行,將獲取到的CorsRegistration對象重新組裝成一個UrlBasedCorsConfigurationSource對象,該對象保存了攔截規(guī)則和CorsConfiguration對象的映射關(guān)系。 - 將新建的
UrlBasedCorsConfigurationSource
對象賦值給AbstractHandlerMapping的corsConfigurationSource屬性 - 當(dāng)請求到達(dá)時的處理方法和
@CrossOrigin
注解處理流程一樣,在AbstractHandlerMapping的getHandler方法處理,從corsConfigurationSource
中獲取CorsConfiguration配置對象,而@CrossOrigin從map中獲取CorsConfiguration對象。如果兩處都可以獲取到CorsConfiguration對象,則獲取到的對象屬性值進行合并。 - 根據(jù)獲取到的
CorsConfiguration
對象構(gòu)造CorsInterceptor攔截器 - 在
CorsInterceptor
攔截器中觸發(fā)對CorsProcessor的processRequest方法調(diào)用,跨域請求的校驗工作將在該方法中完成。
這里的跨域校驗是通過DispatcherServlet中的方法觸發(fā)的,DispatcherServlet在Filter之后執(zhí)行
3.CorsFIlter
@Configuration public class WebMvcConfig { ? ? @Bean ? ? FilterRegistrationBean<CorsFilter> corsFilter() { ? ? ? ? FilterRegistrationBean<CorsFilter> 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; ? ? } }
- 手動創(chuàng)建
CorsConfiguration
對象 - 創(chuàng)建
UrlBasedCorsConfigurationSource
對象,將過濾器的攔截規(guī)則和CorsConfiguration
對象之間的映射關(guān)系由UrlBasedCorsConfigurationSource
中的corsConfiguration
變量保存起來。 - 最后創(chuàng)建
CorsFilter
設(shè)置優(yōu)先級
CorsFilter的doFilterInternal方法:
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); ? ? } }
觸發(fā)對CorsProcessor
的processRequest
方法調(diào)用,跨域請求的校驗工作將在該方法中完成
到此這篇關(guān)于Spring的跨域的幾個方案的文章就介紹到這了,更多相關(guān)Spring的跨域方案內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實現(xiàn)的連接數(shù)據(jù)庫及模糊查詢功能示例
這篇文章主要介紹了java實現(xiàn)的連接數(shù)據(jù)庫及模糊查詢功能,結(jié)合實例形式分析了java基于jdbc連接數(shù)據(jù)庫及使用LIKE語句實現(xiàn)模糊查詢功能的相關(guān)操作技巧,需要的朋友可以參考下2017-12-12Java并發(fā)Map面試線程安全數(shù)據(jù)結(jié)構(gòu)全面分析
本文將探討如何在Java中有效地應(yīng)對這些挑戰(zhàn),介紹一種強大的工具并發(fā)Map,它能夠幫助您管理多線程環(huán)境下的共享數(shù)據(jù),確保數(shù)據(jù)的一致性和高性能,深入了解Java中的并發(fā)Map實現(xiàn),包括ConcurrentHashMap和ConcurrentSkipListMap,及相關(guān)知識點2023-09-09關(guān)于jpa中無法刪除onetomany中many問題的解決
這篇文章主要介紹了關(guān)于jpa中無法刪除onetomany中many問題的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12Java實現(xiàn)爬取往期所有雙色球開獎結(jié)果功能示例
這篇文章主要介紹了Java實現(xiàn)爬取往期所有雙色球開獎結(jié)果功能,涉及Java網(wǎng)頁抓取、正則替換、文件讀寫等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07