1. 概述
在之前的文章中,我們學習了跨域資源共享 (CORS) 規範以及如何在 Spring 中使用它。
在本快速教程中,我們將使用 Spring 的 5 WebFlux 框架設置類似的 CORS 配置。
首先,我們將看到如何啓用該機制在基於註解的 API 中。
然後,我們將分析如何將其啓用為整個項目的全局配置,或者通過使用特殊的 WebFilter。
2. 在標註元素上啓用 CORS
Spring 提供了 註解,用於在控制器類和/或處理方法上啓用 CORS 請求。
2.1. 使用 @CrossOrigin 在請求處理方法中
讓我們將此註解添加到我們的映射請求方法中:
@CrossOrigin
@PutMapping("/cors-enabled-endpoint")
public Mono<String> corsEnabledEndpoint() {
// ...
}我們將會使用一個 WebTestClient (正如我們在本篇“4. 測試”部分所解釋的) 來分析該端點的響應:
ResponseSpec response = webTestClient.put()
.uri("/cors-enabled-endpoint")
.header("Origin", "http://any-origin.com")
.exchange();
response.expectHeader()
.valueEquals("Access-Control-Allow-Origin", "*");此外,我們還可以嘗試發送一個預檢請求,以確保 CORS 配置正常工作:
ResponseSpec response = webTestClient.options()
.uri("/cors-enabled-endpoint")
.header("Origin", "http://any-origin.com")
.header("Access-Control-Request-Method", "PUT")
.exchange();
response.expectHeader()
.valueEquals("Access-Control-Allow-Origin", "*");
response.expectHeader()
.valueEquals("Access-Control-Allow-Methods", "PUT");
response.expectHeader()
.exists("Access-Control-Max-Age");@CrossOrigin 註解具有以下默認配置:
- 允許所有源(這解釋了響應頭中出現的 ‘*’ 值)
- 允許所有頭部
- 處理程序方法映射的所有 HTTP 方法均被允許
- 憑據未啓用
- ‘max-age’ 值設置為 1800 秒(30 分鐘)
但是,可以使用註解的參數覆蓋任何這些值。
2.2. 使用 @CrossOrigin 在控制器上
此註解也支持在類級別使用,並且會影響其所有方法。
如果類級別的配置不適用於所有方法,我們可以對每個元素進行標註以獲得所需的結果:
@CrossOrigin(value = { "http://allowed-origin.com" },
allowedHeaders = { "Baeldung-Allowed" },
maxAge = 900
)
@RestController
public class CorsOnClassController {
@PutMapping("/cors-enabled-endpoint")
public Mono<String> corsEnabledEndpoint() {
// ...
}
@CrossOrigin({ "http://another-allowed-origin.com" })
@PutMapping("/endpoint-with-extra-origin-allowed")
public Mono<String> corsEnabledWithExtraAllowedOrigin() {
// ...
}
// ...
}3. 全局配置中啓用 CORS
我們還可以通過覆蓋 addCorsMappings() 方法來定義全局 CORS 配置,該方法位於 WebFluxConfigurer 實現中。
此外,實現需要添加 @EnableWebFlux 註解,以便在純 Spring 應用中導入 Spring WebFlux 配置。如果使用 Spring Boot,則只有在希望覆蓋自動配置時才需要此註解:
@Configuration
@EnableWebFlux
public class CorsGlobalConfiguration implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry corsRegistry) {
corsRegistry.addMapping("/**")
.allowedOrigins("http://allowed-origin.com")
.allowedMethods("PUT")
.maxAge(3600);
}
}因此,我們已為該特定路徑模式啓用跨域請求處理。
默認配置類似於 @CrossOrigin 配置,但僅允許使用 GET、HEAD 和 POST 方法。
我們還可以將此配置與本地配置組合使用:
- 對於多值屬性,結果的 CORS 配置將是每種規範的組合
- 另一方面,本地值將優先於全局值,對於單值屬性
儘管使用這種方法對於功能端點並非有效,但...
4. 使用 WebFilter 啓用 CORS
啓用功能端點 CORS 的最佳方法是使用 WebFilter。
正如我們在本文中看到的,我們可以使用 WebFilter 來修改請求和響應,同時保持端點的實現不變。
Spring 提供了內置的 CorsWebFilter,以便輕鬆處理跨域配置:
@Bean
CorsWebFilter corsWebFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(Arrays.asList("http://allowed-origin.com"));
corsConfig.setMaxAge(8000L);
corsConfig.addAllowedMethod("PUT");
corsConfig.addAllowedHeader("Baeldung-Allowed");
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}這對於帶有註釋的處理程序也同樣有效,但不能與更精細的 @CrossOrigin 配置結合使用。
我們必須記住,CorsConfiguration 沒有默認配置。
因此,除非我們明確指定所有相關屬性,否則 CORS 實現將非常嚴格。
通過調用對象上的 applyPermitDefaultValues() 方法,可以輕鬆設置默認值。
5. 結論
綜上所述,我們通過非常簡短的示例學習瞭如何在基於 Webflux 的服務中啓用 CORS。
我們看到了不同的方法,因此現在我們唯一需要做的就是分析哪一種方法最符合我們的要求。