SpringBoot項(xiàng)目解決跨域的5種實(shí)現(xiàn)過程
在SpringBoot項(xiàng)目中,解決跨域問題主要有以下5種方式:
1. 使用@CrossOrigin注解
在Controller類或方法上添加注解
// 在類級(jí)別使用 - 該類所有接口都支持跨域
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api")
public class UserController {
// 在方法級(jí)別使用 - 僅此方法支持跨域
@CrossOrigin(origins = "http://localhost:3000")
@GetMapping("/users")
public List<User> getUsers() {
return userService.findAll();
}
@PostMapping("/users")
public User createUser(@RequestBody User user) {
return userService.save(user);
}
}@CrossOrigin參數(shù)說明
@CrossOrigin(
origins = "*", // 允許的源
allowedHeaders = "*", // 允許的請(qǐng)求頭
methods = {RequestMethod.GET, RequestMethod.POST}, // 允許的HTTP方法
allowCredentials = "true", // 是否允許證書
maxAge = 3600 // 預(yù)檢請(qǐng)求緩存時(shí)間
)2. 全局配置 - 實(shí)現(xiàn)WebMvcConfigurer
方式一:配置類方式
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 對(duì)所有接口路徑
.allowedOriginPatterns("*") // 支持域匹配,SpringBoot 2.4+
// .allowedOrigins("*") // SpringBoot 2.4之前版本使用
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}方式二:配置文件方式
# application.yml
spring:
mvc:
cors:
allowed-origins: "*"
allowed-methods: GET,POST,PUT,DELETE,OPTIONS
allowed-headers: "*"
allow-credentials: true
max-age: 36003. 使用CorsFilter過濾器
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
// 1. 創(chuàng)建CORS配置對(duì)象
CorsConfiguration config = new CorsConfiguration();
// 2. 配置CORS規(guī)則
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.setAllowCredentials(true);
config.setMaxAge(3600L);
// 3. 添加映射路徑
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}4. 使用WebFlux配置(響應(yīng)式編程)
如果使用WebFlux,可以這樣配置:
@Configuration
public class CorsWebFluxConfig {
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*");
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.setAllowCredentials(true);
config.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}5. 手動(dòng)配置過濾器
@Component
public class SimpleCorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
// 設(shè)置CORS頭部
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
// 處理預(yù)檢請(qǐng)求
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}生產(chǎn)環(huán)境推薦配置
@Configuration
public class ProductionCorsConfig implements WebMvcConfigurer {
@Value("${cors.allowed-origins:*}")
private String[] allowedOrigins;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOriginPatterns(allowedOrigins)
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("Authorization", "Content-Type", "X-Requested-With")
.exposedHeaders("X-Custom-Header")
.allowCredentials(true)
.maxAge(1800); // 30分鐘
// 管理接口特殊配置
registry.addMapping("/admin/**")
.allowedOriginPatterns("https://admin.example.com")
.allowedMethods("GET", "POST")
.allowCredentials(true);
}
}配置說明文件
# application-prod.yml
cors:
allowed-origins:
- "https://www.example.com"
- "https://api.example.com"總結(jié)對(duì)比
| 方式 | 適用場(chǎng)景 | 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|---|---|
| @CrossOrigin | 單個(gè)接口或控制器 | 精確控制,簡(jiǎn)單易用 | 重復(fù)配置,不夠統(tǒng)一 |
| WebMvcConfigurer | 全局配置 | 統(tǒng)一管理,配置靈活 | 需要?jiǎng)?chuàng)建配置類 |
| CorsFilter | 過濾器級(jí)別 | 處理更底層,性能較好 | 配置相對(duì)復(fù)雜 |
| WebFlux配置 | 響應(yīng)式應(yīng)用 | 專為WebFlux設(shè)計(jì) | 僅適用于響應(yīng)式 |
| 手動(dòng)過濾器 | 完全自定義 | 最大靈活性 | 需要手動(dòng)處理所有細(xì)節(jié) |
推薦使用全局配置(WebMvcConfigurer),因?yàn)樗冉y(tǒng)一又靈活,適合大多數(shù)項(xiàng)目場(chǎng)景。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)字符編碼轉(zhuǎn)換(utf-8/gbk)
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)字符編碼轉(zhuǎn)換工具,主要針對(duì)UTF-8和GBK兩種編碼格式,文中的示例代碼講解詳,需要的可以了解下2025-03-03
Java?數(shù)據(jù)交換?Json?和?異步請(qǐng)求?Ajax詳解
Json(JavaScript Object Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式,采用鍵值對(duì)的形式來表示數(shù)據(jù),它廣泛應(yīng)用于Web開發(fā)中,特別適合于前后端數(shù)據(jù)傳輸和存儲(chǔ),這篇文章主要介紹了Java數(shù)據(jù)交換Json和異步請(qǐng)求Ajax,需要的朋友可以參考下2023-09-09
maven關(guān)于pom文件中的relativePath標(biāo)簽使用
在Maven項(xiàng)目中,子工程通過<relativePath>標(biāo)簽指定父工程的pom.xml位置,以確保正確繼承父工程的配置,這個(gè)標(biāo)簽可以配置為默認(rèn)值、空值或自定義值,默認(rèn)情況下,Maven會(huì)向上一級(jí)目錄尋找父pom;若配置為空值2024-09-09
springboot 實(shí)現(xiàn)長(zhǎng)鏈接轉(zhuǎn)短鏈接的示例代碼
短鏈接服務(wù)通過將長(zhǎng)URL轉(zhuǎn)換成6位短碼,并存儲(chǔ)長(zhǎng)短鏈接對(duì)應(yīng)關(guān)系到數(shù)據(jù)庫(kù)中,用戶訪問短鏈接時(shí),系統(tǒng)通過查詢數(shù)據(jù)庫(kù)并重定向到原始URL,實(shí)現(xiàn)快速訪問,本文就來介紹一下如何使用,感興趣的可以了解一下2024-09-09
解決SpringMVC項(xiàng)目連接RabbitMQ出錯(cuò)的問題
這篇文章主要介紹了解決SpringMVC項(xiàng)目連接RabbitMQ出錯(cuò)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01
JavaEE初階教程之Java?IO流讀寫與文件操作實(shí)戰(zhàn)
在Java編程中IO流是進(jìn)行文件讀寫操作的重要組成部分,IO流提供了一種靈活、可靠的方式來處理文件和數(shù)據(jù)流,這篇文章主要介紹了JavaEE初階教程之Java?IO流讀寫與文件操作實(shí)戰(zhàn)的相關(guān)資料,需要的朋友可以參考下2025-12-12

