在 Spring Boot 中解決跨域問題(CORS)主要有三種常用方式,下面詳細說明每種實現方法:
方案一:全局配置(推薦)
在配置類中實現 WebMvcConfigurer
接口,統一配置所有接口的跨域規則:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 所有接口// Spring Boot 2.4+ 使用 allowedOriginPatterns.allowedOriginPatterns("*") // 允許的請求方法.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允許的請求頭.allowedHeaders("*") // 是否允許發送Cookie.allowCredentials(true) // 預檢請求緩存時間(秒).maxAge(3600); }
}
方案二:控制器注解配置
在單個控制器或方法上使用 @CrossOrigin
注解:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
// 類級別配置(整個控制器生效)
@CrossOrigin(origins = "http://localhost:8080", allowCredentials = "true")
public class UserController {// 方法級別配置(覆蓋類配置)@GetMapping("/users")@CrossOrigin(maxAge = 1800)public List<User> getUsers() {return userService.getAllUsers();}
}
方案三:過濾器配置(適合WebFlux或特殊需求)
創建自定義CORS過濾器:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;@Configuration
public class GlobalCorsConfig {@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();// 允許所有域名(生產環境建議指定具體域名)config.addAllowedOriginPattern("*");// 允許發送Cookieconfig.setAllowCredentials(true);// 允許所有請求頭config.addAllowedHeader("*");// 允許所有方法config.addAllowedMethod("*");// 預檢請求緩存時間config.setMaxAge(3600L);UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}
}
常見問題解決方案
-
Credentials 與 Origin 沖突問題
- 現象:前端攜帶 Cookie 時報錯
- 解決:
// 正確配置 .allowCredentials(true) // 使用 allowedOriginPatterns 替代 allowedOrigins .allowedOriginPatterns("http://trusted-domain.com")
- 前端配合:
fetch(url, {credentials: 'include' // 必須 })
-
Spring Security 集成問題
在 Security 配置中啟用 CORS:@Override protected void configure(HttpSecurity http) throws Exception {http.cors() // 啟用 CORS.and()// ... 其他安全配置 }
-
OPTIONS 請求被攔截
- 確保未手動攔截 OPTIONS 方法
- 在 Security 配置中添加:
.antMatchers(HttpMethod.OPTIONS).permitAll()
-
多配置沖突
- 優先級:過濾器 > 全局配置 >
@CrossOrigin
- 建議整個項目統一使用一種配置方式
- 優先級:過濾器 > 全局配置 >
最佳實踐建議
-
開發環境
使用全局配置 +allowedOriginPatterns("*")
快速開發 -
生產環境
.allowedOriginPatterns("https://your-domain.com","https://api.your-domain.com" )
-
安全加固
// 限制允許的請求頭 .allowedHeaders("Content-Type", "X-Requested-With", "Authorization") // 暴露特定響應頭 .exposedHeaders("Custom-Header")
重要提示:
- Spring Boot 2.4.x+ 必須使用
allowedOriginPatterns
替代舊版allowedOrigins
- 開啟
allowCredentials(true)
時,禁止使用allowedOriginPatterns("*")
(瀏覽器安全限制),應指定具體域名