淺析SpringBoot如何解決CORS問題
在前后端分離的開發(fā)模式中,前端調(diào)用后端接口時,經(jīng)常會遇到 跨域資源共享(CORS) 的問題。Spring Boot 作為常用的后端框架,提供了多種方式來優(yōu)雅地解決這個問題。本文將全面介紹 Spring Boot 中處理 CORS 的常見方法、原理分析及注意事項,幫助開發(fā)者高效排查和解決跨域問題。
一、什么是 CORS
CORS(Cross-Origin Resource Sharing,跨域資源共享)是瀏覽器的一種安全策略,用于防止頁面被惡意地從一個域加載資源到另一個域。簡單來說,只要前端請求的協(xié)議、域名、端口與后端接口不完全一致,就屬于跨域請求。
例如:
- 前端地址:http://localhost:3000
- 后端接口:http://localhost:8080/api/data
這就構(gòu)成了跨域請求,瀏覽器會默認(rèn)攔截這類請求,除非服務(wù)器端明確允許跨域訪問。
二、Spring Boot 中解決 CORS 的幾種方法
Spring Boot 提供了多種方式來配置和處理跨域問題,以下是最常用的三種方法:
方法一:使用 @CrossOrigin 注解(推薦用于小型項目或測試)
這是 Spring Boot 提供的快捷方式,可直接作用于控制器類或方法上:
@RestController @RequestMapping("/api") @CrossOrigin(origins = "http://localhost:3000") public class MyController { @GetMapping("/data") public String getData() { return "Hello, CORS!"; } }
參數(shù)說明:
origins:允許的域名(可為 * 表示所有)。
methods:允許的方法,如 GET, POST 等。
maxAge:預(yù)檢請求的有效時間(單位秒)。
allowedHeaders:允許攜帶的頭信息。
缺點:對于中大型項目來說,控制器眾多,維護(hù)成本高。
方法二:全局 CORS 配置(推薦用于中大型項目)
通過實現(xiàn) WebMvcConfigurer 接口,全局統(tǒng)一配置跨域規(guī)則,適用于大多數(shù)項目場景。
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 所有接口 .allowedOrigins("http://localhost:3000") // 允許的前端地址 .allowedMethods("GET", "POST", "PUT", "DELETE") // 允許的方法 .allowedHeaders("*") // 允許的請求頭 .allowCredentials(true) // 允許攜帶 Cookie .maxAge(3600); // 預(yù)檢請求緩存時間(秒) } }
優(yōu)點:配置集中,維護(hù)簡單,推薦使用。
方法三:通過 Filter 手動設(shè)置響應(yīng)頭(不推薦,除非特殊需求)
手動注冊一個過濾器,向響應(yīng)中添加 CORS 相關(guān)頭信息:
@Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res = (HttpServletResponse) response; HttpServletRequest req = (HttpServletRequest) request; res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); res.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); res.setHeader("Access-Control-Allow-Headers", "*"); res.setHeader("Access-Control-Allow-Credentials", "true"); // OPTIONS 預(yù)檢請求直接返回 if ("OPTIONS".equalsIgnoreCase(req.getMethod())) { res.setStatus(HttpServletResponse.SC_OK); } else { chain.doFilter(request, response); } } }
缺點:易出錯,不易維護(hù),建議使用 WebMvcConfigurer 方式代替。
三、常見問題排查
OPTIONS 請求返回 403 或沒有響應(yīng)?
確保后端允許 OPTIONS 方法。
確保沒有被 Spring Security 攔截。
攜帶 Cookie 不生效?
后端必須設(shè)置:.allowCredentials(true)
前端必須設(shè)置:axios.defaults.withCredentials = true
Spring Security 攔截 CORS 請求?
需要額外配置 CORS 策略,示例如下:
@EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors() // 啟用 CORS .and() .csrf().disable() .authorizeHttpRequests() .anyRequest().permitAll(); return http.build(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(List.of("http://localhost:3000")); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); config.setAllowedHeaders(List.of("*")); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } }
四、總結(jié)
方法 | 場景 | 推薦度 |
---|---|---|
@CrossOrigin 注解 | 控制器少,接口固定 | ?? |
實現(xiàn) WebMvcConfigurer | 中大型項目,統(tǒng)一配置 | ????? |
自定義 Filter | 特殊需求(如動態(tài)域) | ? |
CORS 配置看似簡單,但與前端請求設(shè)置、Spring Security 配合使用時需格外注意。建議在項目初始化階段就進(jìn)行統(tǒng)一的跨域策略設(shè)計,避免后續(xù)頻繁調(diào)整。
到此這篇關(guān)于淺析SpringBoot如何解決CORS問題的文章就介紹到這了,更多相關(guān)SpringBoot解決CORS內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實現(xiàn)HTTP調(diào)用的七種方式總結(jié)
小編在工作中,遇到一些需要調(diào)用三方接口的任務(wù),就需要用到 HTTP 調(diào)用工具,這里,我總結(jié)了一下 實現(xiàn) HTTP 調(diào)用的方式,共有 7 種(后續(xù)會繼續(xù)新增),需要的朋友可以參考下2023-09-09springboot啟動前執(zhí)行方法的四種方式總結(jié)
這篇文章主要給大家介紹了關(guān)于springboot啟動前執(zhí)行方法的四種方式,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-01-01詳解SpringBoot中的tomcat優(yōu)化和修改
這篇文章主要介紹了詳解SpringBoot中的tomcat優(yōu)化和修改,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09用SpringBoot Admin監(jiān)控SpringBoot程序
這篇文章主要介紹了用SpringBoot Admin監(jiān)控SpringBoot程序,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下2020-10-10Java ApiPost請求返回406狀態(tài)碼問題的解決方案
APIPost是一款專為開發(fā)者和測試人員設(shè)計的API測試工具,類似于Postman,但提供了更多的團(tuán)隊協(xié)作和文檔管理功能,它可以幫助你更好地進(jìn)行接口調(diào)試和集成測試,但遇到了請求后返回的是406狀態(tài),所以本文給大家介紹了Java ApiPost請求返回406狀態(tài)碼問題的解決方案2025-04-04Java調(diào)用微信客服消息實現(xiàn)發(fā)貨通知的方法詳解
這篇文章主要介紹了Java調(diào)用微信客服消息實現(xiàn)發(fā)貨通知的方法,結(jié)合實例形式詳細(xì)分析了java針對微信接口調(diào)用的原理、調(diào)用方法與相關(guān)注意事項,需要的朋友可以參考下2017-08-08Java面向?qū)ο笾甪inal關(guān)鍵字詳細(xì)解讀
這篇文章主要介紹了Java面向?qū)ο笾甪inal關(guān)鍵字詳細(xì)解讀,final修飾的屬性又叫常量,一般用 XX_XX_XX來命名,final修飾的屬性在定義時必須賦初始值,并且以后不能再修改,需要的朋友可以參考下2024-01-01