Spring Boot 結合 CORS 解決前端跨域問題

Spring Boot 結合 CORS 解決前端跨域問題

1. 背景

在前后端分離的項目中,前端(例如 http://localhost:3000)調用后端接口(例如 http://localhost:8080)時,瀏覽器會因為 同源策略 限制而阻止請求,這就是所謂的 跨域問題

同源策略要求:

  • 協議(Protocol)
  • 域名(Domain)
  • 端口(Port)

三者必須完全一致,否則就會觸發跨域。

跨域在前端調試、微服務接口調用、第三方 API 請求等場景中非常常見。為了讓瀏覽器允許跨域訪問,需要配置 CORS(跨域資源共享,Cross-Origin Resource Sharing)


2. 什么是 CORS

CORS 是 W3C 定義的一種跨域訪問標準,允許服務器在響應中添加特定的 HTTP 頭,讓瀏覽器判斷是否允許跨域請求。核心是以下響應頭:

響應頭作用
Access-Control-Allow-Origin允許訪問的源(可以是具體域名或 *
Access-Control-Allow-Methods允許的 HTTP 方法(GET, POST, PUT, DELETE 等)
Access-Control-Allow-Headers允許的自定義請求頭
Access-Control-Allow-Credentials是否允許攜帶 Cookie
Access-Control-Max-Age預檢請求緩存時間(秒)

3. Spring Boot 中解決跨域的常用方法

3.1 方法一:在 Controller 上使用 @CrossOrigin

Spring Boot 提供了 @CrossOrigin 注解,可以快速在類或方法級別開啟 CORS。

import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/user")
@CrossOrigin(origins = "http://localhost:3000") // 允許的前端地址
public class UserController {@GetMapping("/{id}")public String getUser(@PathVariable Long id) {return "用戶ID: " + id;}
}

特點

  • 適合局部跨域控制。
  • 不影響其他接口。
  • 缺點是需要在每個 Controller 手動加注解,管理不便。

3.2 方法二:全局 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 GlobalCorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 允許跨域的接口路徑.allowedOriginPatterns("*") // 允許跨域的源(Spring Boot 2.4+ 推薦用 allowedOriginPatterns).allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允許的 HTTP 方法.allowedHeaders("*") // 允許的請求頭.allowCredentials(true) // 是否允許攜帶 Cookie.maxAge(3600); // 預檢請求緩存時間}
}

特點

  • 一次配置,所有接口生效。
  • 方便統一管理。
  • 生產環境建議改成精確匹配允許的域名,而不是 *

3.3 方法三:使用 Filter 配置 CORS

通過自定義 CorsFilter 處理跨域請求,可以在 Spring Boot 啟動時加載。

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 CorsFilterConfig {@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedOriginPattern("*");config.setAllowCredentials(true);config.addAllowedMethod("*");config.addAllowedHeader("*");config.setMaxAge(3600L);UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}
}

特點

  • 適用于需要跨越 Spring MVC、Spring Security 等多個層的情況。
  • 能解決某些全局配置不生效的問題。

4. 配合 Spring Security 的特殊處理

如果項目使用了 Spring Security,默認會攔截 OPTIONS 預檢請求,導致 CORS 配置不生效。這時需要額外在 Security 配置中開放 OPTIONS 請求。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;@Configuration
public class SecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.cors().and().csrf().disable(); // 啟用 CORS & 禁用 CSRFhttp.authorizeHttpRequests().anyRequest().permitAll();return http.build();}
}

關鍵點

  • http.cors() 會讀取 WebMvcConfigurerCorsFilter 中的配置。
  • 關閉 CSRF 主要是為了方便調試跨域(生產環境需根據業務需求啟用)。

5. 常見問題排查

  1. 前端依舊報跨域
    • 確認是瀏覽器報的 CORS 錯誤,而不是接口 404/500。
    • 確認后端響應中包含 Access-Control-Allow-Origin
  2. Cookie 不生效
    • 后端 allowCredentials(true)
    • 前端請求設置 fetch 或 Axios 的 withCredentials: true
    • 注意:當 allowCredentials(true) 時,Access-Control-Allow-Origin 不能為 *
  3. Spring Security 版本沖突
    • Spring Boot 3.x 下要用 SecurityFilterChain 而不是 WebSecurityConfigurerAdapter(已廢棄)。

6. 總結

  • 局部跨域@CrossOrigin
  • 全局跨域(推薦)WebMvcConfigurer
  • 復雜場景(如結合 Spring Security) → CorsFilter + SecurityConfig
  • 生產環境建議精確配置 allowedOrigins,避免安全隱患。

? 最佳實踐推薦

@Configuration
public class GlobalCorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("https://yourdomain.com") // 精確指定.allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*").allowCredentials(true).maxAge(3600);}
}

配合:

@Configuration
public class SecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.cors().and().csrf().disable();return http.build();}
}

這樣前端就可以愉快地調用后端接口而不會再被 CORS 卡住了。


7.本質

CORS 在 Spring Boot 里的本質,其實并不是靠普通的 攔截器(HandlerInterceptor) 去做的,而是由 底層的 CORS 處理機制 在 Servlet Filter 層完成的。


7.1. 核心機制

在 Spring Web(Spring MVC)里,CORS 處理是通過 CorsProcessor 在請求進入 Controller 之前攔截,并根據配置動態添加 CORS 響應頭。
整個流程分兩種情況:

  1. 預檢請求(OPTIONS)
    • 瀏覽器先發一個 OPTIONS 請求,詢問服務器是否允許該跨域。
    • Spring 的 CORS 處理器判斷后直接返回帶有 Access-Control-Allow-* 的響應,并終止后續調用,不進入 Controller。
  2. 實際請求(GET、POST…)
    • 在進入 Controller 前,CORS 處理器檢查請求來源和方法是否合法,如果允許,就在響應頭里加上 CORS 相關字段。

7.2. Spring Boot 的執行鏈

當你用

  • @CrossOrigin
  • WebMvcConfigurer#addCorsMappings()
  • CorsFilter

配置 CORS 后,Spring Boot 會:

  1. 注冊一個 CorsFilterHandlerMappingIntrospector 內部的 CORS 攔截邏輯。
  2. 請求進入 Servlet 容器后,先走 Filter 鏈,Spring CORS 邏輯會最先判斷跨域。
  3. 如果是 OPTIONS 預檢且允許跨域,直接返回響應,不再走后續 Controller。
  4. 如果是實際請求,進入 Controller 處理業務邏輯,但響應會自動加上 CORS 頭。

7.3. 為什么不用普通攔截器

  • 普通的 HandlerInterceptor 只能攔截已經匹配到 Handler 的請求,但 CORS 預檢請求往往不需要進入業務 Controller。
  • CORS 要盡早處理,最好在 Filter 層攔截,這樣性能更好、邏輯更統一。
  • Spring MVC 的 CORS 是在 DispatcherServlet 處理請求前就能處理的,而攔截器是在 HandlerAdapter 調用前才運行。

? 總結一句話:
Spring Boot 的 CORS 本質是通過 Servlet Filter 層的 CorsFilter + Spring MVC 的 CorsProcessor 在請求到達 Controller 前處理的,而不是靠普通的業務攔截器實現的。

img


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918102.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918102.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918102.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GPT-5 發布:微小進步難掩瓶頸,AI 行業或迎冷靜

北京時間 8 月 8 日凌晨,OpenAI 的 GPT-5 在萬眾期待中登場。距離 GPT-4 發布已過去兩年半,然而這場發布會卻未重現 ChatGPT 初現時的驚艷,也沒有 GPT-4 的跨越式升級,更無 o1 發布時的震撼。1 小時 20 分鐘的發布會,充斥著不驚艷的測試數據、與競品難分高下的用例展示,甚…

僵尸進程、孤兒進程、進程優先級、/proc 文件系統、CRC 與網絡溢出問題處理(實戰 + 原理)

僵尸進程 / 孤兒進程:是什么、為什么會出現、如何定位與清理進程優先級:nice/priority、CFS 與實時調度、I/O 優先級、cgroup 限流/proc 文件系統:最常用路徑與診斷手法CRC 校驗:在存儲/網絡里的作用與局限、抓包“校驗錯誤”的常…

GPT-5 不僅是版本升級,它標志著 推理能力的商業化 和 Agent操作系統 的崛起,開啟了 AI革命時代。

GPT-5 不僅是版本升級,它標志著 推理能力的商業化 和 Agent操作系統 的崛起,開啟了 AI革命時代。 核心技術亮點: 商業化推理能力:AI不僅生成文本,還能 自動解決復雜任務,提升工作效率。 Agent操作系統&…

【C#】掌握并發利器:深入理解 .NET 中的 Task.WhenAll

在現代 .NET 應用程序開發中,異步編程(Asynchronous Programming)已成為提升性能、改善響應能力和充分利用多核處理器的關鍵技術。async 和 await 關鍵字極大地簡化了異步代碼的編寫,而 Task 類則是這一模型的核心。在處理多個并發…

微型導軌在半導體制造中有哪些高精密應用場景?

微型導軌在半導體制造中用于晶圓對準和定位系統,確保晶圓在光刻、蝕刻等工藝中精確移動。其高精度、高剛性、低摩擦和緊湊設計等特性,使其成為半導體設備實現微米級運動控制的核心部件。光刻機:在光刻工藝中,微型導軌支撐并引導掩…

全棧:Tomcat 安裝教程

Tomcat 安裝教程 安裝 Tomcat 的步驟因操作系統而異,以下是 Windows、Linux 和 Mac 系統的詳細安裝方法: 一、Windows 系統安裝 Tomcat 下載 Tomcat 訪問 Tomcat 官方網站(http://tomcat.apache.org/),選擇適合的版本…

數據分析——Pandas庫

Pandas是Python生態系統中最強大、最流行的數據分析庫,專為處理結構化數據(如表格和時間序列)而設計。它提供了高效的數據結構和豐富的功能,使得數據清洗、轉換、分析和可視化變得簡單直觀。一、Pandas庫的安裝詳解1. 安裝前的準備…

數據結構-哈希表(散列表)

1.基本概念哈希表(散列表):提高數據的查找效率哈希存儲:將要存儲的數據的關鍵字和存儲位置之間,建立起對應的關系, 這個關系稱之為哈希函數。存儲數據時,通過對應的哈希函數可以將數據映射到指定…

如何在Vue中使用拓撲圖功能

前言 該組件基于 Vue.js 和 AntV G6 構建項目特色功能 1. 豐富的節點圖標支持 本拓撲圖系統的最大特色是支持使用自定義圖片作為節點圖標 2. 智能的力導向布局 系統采用力導向布局算法,能夠自動優化節點位置,避免重疊,形成美觀的網絡拓撲結構…

基于dynamic的Druid 與 HikariCP 連接池集成配置區別

你提供的內容是關于 ??dynamic-datasource-spring-boot-starter?? 的詳細介紹,這是一個非常實用的 ??Spring Boot 多數據源動態切換組件??,適用于需要在單個應用中連接多個數據庫并靈活切換數據源的場景。下面我為你梳理一下該組件的核心信息與使…

算法訓練之棧

???~~~~~~歡迎光臨知星小度博客空間~~~~~~??? ???零星地變得優秀~也能拼湊出星河~??? ???我們一起努力成為更好的自己~??? ???如果這一篇博客對你有幫助~別忘了點贊分享哦~??? ???如果有什么問題可以評論區留言或者私信我哦~??? ??????個人…

OpenAI 最新開源模型 gpt-oss (Windows + Ollama/ubuntu)本地部署詳細教程

OpenAI 最近發布了其首個開源的開放權重模型gpt-oss,這在AI圈引起了巨大的轟動。對于廣大開發者和AI愛好者來說,這意味著我們終于可以在自己的機器上,完全本地化地運行和探索這款強大的模型了。 本教程將一步一步指導你如何在Windows系統上&…

在X86架構Linux中創建虛擬根目錄并下載指定架構(如aarch64)的軟件包(含依賴)

在X86架構Linux中創建虛擬根目錄并下載指定架構(如aarch64)的軟件包(含依賴) 在Linux系統中,有時候我們需要在特定的環境或架構下安裝軟件包,而不影響主系統。一種常見的方法是創建一個虛擬的根目錄,并在此環境中操作。本文將介紹如何通過創建…

scratch筆記和練習-第9課:一起來繪畫

位圖也稱為點陣圖,它是由許許多多的點組成的,這些點被稱為像素。位圖圖像可以表現豐富的多彩變化 并產生逼真的效果,很容易在不同軟件之間交換使用, 但它在保存圖像時需要記錄每一個像素的色彩信息,所以占用的存儲空間…

[linux] Linux:一條指令更新DDNS

Linux:一條指令更新DDNS 在動態IP環境下,如何確保我們的域名始終指向正確的公網IP地址?動態DNS(DDNS)服務為我們提供了完美的解決方案。今天,我將分享一個簡潔高效的Linux命令行指令,用于自動更…

[激光原理與應用-182]:測量儀器 - 光束型 - 光束質量分析儀

光束質量分析儀是用于精確評估激光光束特性的核心設備,通過測量光束的強度分布、相位分布、發散角等參數,為激光系統的優化、加工工藝控制及科研實驗提供關鍵數據支持。以下是光束質量分析儀的詳細解析:一、核心功能 - 光束強度分布分析測量內…

Linux 限制 root 登錄 IP 地址的方法

Linux 限制 root 登錄 IP 地址的方法Linux 限制 root 登錄 IP 地址的方法方法一:修改 SSH 配置文件方法二:使用 hosts.allow 和 hosts.deny 文件方法三:使用防火墻規則方法四:使用 access.conf 文件注意事項Linux 限制 root 登錄 …

Word中怎樣插入特殊符號

使用 “插入” 菜單:插入常用符號:將光標置于要插入符號的位置,點擊 “插入” 選項卡,在 “符號” 組中點擊 “符號” 按鈕,會彈出一個符號庫,里面包含了常見的標點符號、特殊字符等,找到所需符…

Linux 內核發包流程與路由控制實戰

Linux 內核發包流程與路由控制實戰 在網絡調優、性能優化、SDN、NFV、容器網絡等場景下,理解 Linux 內核發包路徑和路由控制機制是必修課。 本文將從內核網絡棧的原理入手,再結合 iproute2 命令和 策略路由給出實戰案例。一、Linux 內核發包流程&#xf…

點播服務器

早期的時候,用 live555 作為 rtsp 點播服務器;現在比較常用的 流媒體服務器比較多;這里比較簡單的,可以用 ZLMediakit;可以支持 ffmeg 退流 到ZLMediakit,然后別的客戶端從 ZLMediakit 服務器拉流&#xff…