SpringCloud微服務(wù)中跨域配置的方法詳解
跨域,指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對 javascript 施加的安全限制。
同源策略,指的是協(xié)議,域名,端口都要相同,其中有一個(gè)不同都會(huì)產(chǎn)生跨域。
跨域相關(guān)含義:
- Access-Control-Allow-Origin:服務(wù)器允許請求的源;
- Access-Control-Allow-Headers: 服務(wù)器允許使用的頭;
- Access-Control-Allow-Methods: 真實(shí)請求允許的方法;
- Access-Control-Allow-Credentials: 是否允許用戶發(fā)送、處理 cookie;
- Access-Control-Max-Age: 預(yù)檢請求的有效期,單位為秒。有效期內(nèi),不會(huì)重復(fù)發(fā)送預(yù)檢請求;
Java微服務(wù)中解決跨域問題主要分為如下情況:
情況1:針對單個(gè)服務(wù)的跨域問題,增加允許跨域配置類即可。
如,前端vue+業(yè)務(wù)微服務(wù)
情況2:有網(wǎng)關(guān)時(shí),網(wǎng)關(guān)配置允許跨域,微服務(wù)不配置。微服務(wù)項(xiàng)目網(wǎng)關(guān)服務(wù)為Spring Cloud Gateway,則要求所有請求統(tǒng)一走網(wǎng)關(guān),無需給每個(gè)微服務(wù)都配置跨域,只需要給網(wǎng)關(guān)微服務(wù)gateway配置跨域即可。
如,前端vue+網(wǎng)關(guān)服務(wù)gateway+業(yè)務(wù)微服務(wù)
情況3:有網(wǎng)關(guān)時(shí),網(wǎng)關(guān)配置允許跨域,微服務(wù)配置允許跨域。需要在網(wǎng)關(guān)的配置里加上重復(fù)請求頭。配置DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_UNIQUE
。此時(shí)走不走網(wǎng)關(guān),都沒有跨域問題。
如,前端vue+網(wǎng)關(guān)服務(wù)gateway+業(yè)務(wù)微服務(wù)/認(rèn)證授權(quán)微服務(wù)
情況4:網(wǎng)關(guān)不配置,微服務(wù)配置允許跨域。請求如果走網(wǎng)關(guān),則會(huì)存在跨域問題。不走網(wǎng)關(guān),直接訪問微服務(wù),沒有跨域問題。
情況5:網(wǎng)關(guān)不配置,微服務(wù)不配置。走不走網(wǎng)關(guān)都會(huì)存在跨域問題。
情況1
單個(gè)springboot微服務(wù)的跨域配置如下
若springboot版本為2.4.0以前,則設(shè)置請求源為
corsConfiguration.addAllowedOrigin(“*”);
若springboot版本為2.4.0以后,則設(shè)置請求源為
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList(“*”));
@Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { // 跨域配置源 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); //設(shè)置跨域的配置信息 CorsConfiguration corsConfiguration = new CorsConfiguration(); //1,允許任何來源 corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*")); //2,允許任何請求頭 corsConfiguration.addAllowedHeader(CorsConfiguration.ALL); //3,允許任何方法 corsConfiguration.addAllowedMethod(CorsConfiguration.ALL); //4,允許憑證 corsConfiguration.setAllowCredentials(true); source.registerCorsConfiguration("/**", corsConfiguration); return new CorsFilter(source); } }
其中,若在springboot2.3.10版本中使用corsConfiguration.addAllowedOrigin(“*”);是可以解決跨域問題的,若在springboot2.7.0版本中使用,會(huì)發(fā)現(xiàn)報(bào)跨域問題,查看后臺(tái)日志提示如下異常:
When allowCredentials is true, allowedOrigins cannot contain the special value "*"since that cannot be set on the “Access-Control-Allow-Origin” response header. To allow credentials to a set of origins, list them explicitly or consider using “allowedOriginPatterns” instead.
可見,不能在 corsConfiguration.setAllowCredentials(true)的時(shí)候?qū)ddAllowedOrigin設(shè)置為"*",而要使用 allowedOriginPatterns這個(gè)字段來設(shè)置origin。
其實(shí),也可以采用重寫WebMvcConfigurer的方式或使用注解@CrossOrigin的方式。
情況2
gateway網(wǎng)關(guān)服務(wù)中跨域配置類如下
若springboot版本為2.4.0以前,則設(shè)置請求源為
corsConfiguration.addAllowedOrigin(“*”);
若springboot版本為2.4.0以后,則設(shè)置請求源為
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList(“*”));
@Configuration public class CorsConfig { @Bean public CorsWebFilter corsFilter() { // 跨域配置源 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); //設(shè)置跨域的配置信息 CorsConfiguration corsConfiguration = new CorsConfiguration(); // 允許所有請求來源進(jìn)行跨域 //corsConfiguration.addAllowedOrigin("*"); // spring boot2.4以后的配置 corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*")); // 允許所有頭進(jìn)行跨域 corsConfiguration.addAllowedHeader("*"); // 允許所有請求方式進(jìn)行跨域 corsConfiguration.addAllowedMethod("*"); // 允許攜帶cookie進(jìn)行跨域 corsConfiguration.setAllowCredentials(true); //任意路徑都需要跨域配置 source.registerCorsConfiguration("/**", corsConfiguration); return new CorsWebFilter(source); } }
注:需要去掉業(yè)務(wù)微服務(wù)的跨域配置,防止多次跨域配置。
其實(shí),也可以采用在gateway網(wǎng)關(guān)服務(wù)的application.yml文件中配置的方式,如:
spring:
cloud:
gateway:
# 全局的跨域配置
globalcors:
# 解決options請求被攔截問題
add-to-simple-url-handler-mapping: true
cors-configurations:
# 攔截的請求
'[/**]':
# 允許跨域的請求
#allowedOrigins: "*" # spring boot2.4以前的配置
allowedOriginPatterns: "*" # spring boot2.4以后的配置
# 允許請求中攜帶的頭信息
allowedHeaders: "*"
# 運(yùn)行跨域的請求方式
allowedMethods: "*"
# 是否允許攜帶cookie
alloweCredentials: true
# 跨域檢測的有效期,單位s
maxAge: 36000
不要出現(xiàn)重復(fù)解決跨域問題,若之前用過注解@CrossOrigin,然后又添加了過濾器,就會(huì)導(dǎo)致重復(fù),僅用過濾器就OK了。
情況3
當(dāng)gateway網(wǎng)關(guān)服務(wù)設(shè)置了跨域,業(yè)務(wù)微服務(wù)也設(shè)置了跨域,則需要在網(wǎng)關(guān)的配置里加上重復(fù)請求頭,如
pring:
cloud:
gateway:
globalcors:
default-filters:
- DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Headers Access-Control-Allow-Credentials,RETAIN_UNIQUE
當(dāng)業(yè)務(wù)微服務(wù)集成了security+oauth2,會(huì)出現(xiàn)跨域失效的情況,需要在WebSecurityConfig配置類和ResourceServerConfig配置類中開啟CORS,如下
@Override protected void configure(HttpSecurity http) throws Exception { http .cors() .and() .csrf().disable(); }
@Override public void configure(HttpSecurity http) throws Exception { http .cors() .and() .csrf().disable(); }
當(dāng)gateway網(wǎng)關(guān)微服務(wù)集成了security+oauth2,又會(huì)出現(xiàn)跨域問題,則需要在ResourceServerConfig配置類中加入跨域過濾器,如下
@Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException { http.cors().and().csrf().disable(); http.addFilterBefore(corsWebFiler, SecurityWebFiltersOrder.CORS); }
跨域問題:The ‘Access-Control-Allow-Origin’ header contains multiple values “*, *”, but only one is allowed.
分析:通??缬騿栴}可以在三個(gè)地方解決:
- 在微服務(wù)的代碼中通過跨域配置類解決;
- 在網(wǎng)關(guān)中解決,可以通過配置類,也可以通過yml配置;
- 在nginx或vue中解決;
以上3種方式,若使用了2種,則會(huì)出現(xiàn)雙重跨域的問題。那么若是知道那里用了2次跨域配置,選擇去掉一個(gè)即可;若是2個(gè)地方都不想去掉,還可以在網(wǎng)關(guān)中通過yml配置來忽略掉雙重跨域的問題。
spring:
main:
allow-bean-definition-overriding: true
gateway:
discovery: 默認(rèn)為false,設(shè)為true便開啟通過服務(wù)中心的自動(dòng)根據(jù) serviceId 創(chuàng)建路由的功能。
locator:
enabled: true
lowerCaseServiceId: true
#解決跨域問題
globalcors:
corsConfigurations:
'[/**]':
# 允許攜帶認(rèn)證信息
allow-credentials: true
# 允許跨域的源(網(wǎng)站域名/ip),設(shè)置*為全部
allowedOrigins: "*"
# 允許跨域的method, 默認(rèn)為GET和OPTIONS,設(shè)置*為全部
allowedMethods: "*"
# 允許跨域請求里的head字段,設(shè)置*為全部
allowedHeaders: "*"
#解決雙重跨域 RETAIN_FIRST RETAIN_LAST RETAIN_UNIQUE
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials Vary, RETAIN_UNIQUE
具體跨域問題還需根據(jù)具體情況分析解決。
到此這篇關(guān)于SpringCloud微服務(wù)中跨域配置的方法詳解的文章就介紹到這了,更多相關(guān)SpringCloud跨域配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java HttpURLConnection超時(shí)和IO異常處理
這篇文章主要介紹了Java HttpURLConnection超時(shí)和IO異常處理的相關(guān)資料,需要的朋友可以參考下2016-09-09Java語言中finally是否一定會(huì)執(zhí)行你知道嗎
這篇文章主要為大家詳細(xì)介紹了Java finally是否一定會(huì)執(zhí)行,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02myBatis組件教程之緩存的實(shí)現(xiàn)與使用
這篇文章主要給大家介紹了關(guān)于myBatis組件教程之緩存的實(shí)現(xiàn)與使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11Java開發(fā)必備知識(shí)之?dāng)?shù)組詳解
數(shù)組對于每一門編程語言來說都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語言對數(shù)組的實(shí)現(xiàn)及處理也不盡相同.本篇文章為大家整理了Java最全關(guān)于數(shù)組的知識(shí)點(diǎn),并給出其對應(yīng)的代碼,需要的朋友可以參考下2021-06-06Spring如何基于Proxy及cglib實(shí)現(xiàn)動(dòng)態(tài)代理
這篇文章主要介紹了Spring如何基于Proxy及cglib實(shí)現(xiàn)動(dòng)態(tài)代理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06spring注入在有常量的情況下使用@AllArgsConstructor操作
這篇文章主要介紹了spring注入在有常量的情況下使用@AllArgsConstructor操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09SpringBoot雪花算法主鍵ID傳到前端后精度丟失問題的解決
本文主要介紹了SpringBoot雪花算法主鍵ID傳到前端后精度丟失問題的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08