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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…