Springboot解决跨域的五种方式

在 Spring Boot 中解决跨域(CORS,Cross-Origin Resource Sharing)问题有 多种方式,适用于不同场景。下面系统地介绍 5 种主流方法,从简单到灵活,附代码示例和适用场景。

方法 1:使用 @CrossOrigin 注解(最简单)

适用场景: 单个 Controller 或方法需要跨域

java 复制代码
@RestController
@CrossOrigin(origins = "http://localhost:3000") // 允许指定来源
public class UserController {

    @GetMapping("/user")
    public User getUser() {
        return new User("John");
    }

    // 或只对某个方法生效
    @CrossOrigin(origins = "*") // 允许所有来源(生产环境慎用!)
    @PostMapping("/save")
    public String save() {
        return "ok";
    }
}

优点:

  • 简单、直观
  • 可细粒度控制(类级别 or 方法级别)

缺点:

  • 无法全局统一管理
  • 不适合大型项目

✅ 方法 2:全局配置 CORS(推荐!)

适用场景: 整个应用统一处理跨域(最常用)

方式 A:实现 WebMvcConfigurer 接口(Spring Boot 2.x+)

java 复制代码
@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 拦截所有路径
                .allowedOrigins("*")
                // .allowedOrigins("http://localhost:3000", "https://your-app.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                // .allowCredentials(true) // 是否允许携带 cookie,⚠️ 注意:这里不能同时设为 true!
                .maxAge(3600); // 预检请求缓存时间(秒)
    }
}

方式 B:使用 @Bean 注册 CorsConfigurationSource

java 复制代码
@Configuration
public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
        // config.setAllowedOrigins(Arrays.asList("*")); // 👈 允许所有域
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowCredentials(true);
        // config.setAllowCredentials(true); // ⚠️ 不能与 "*" 同时使用!

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

优点:

  • 全局生效,配置集中
  • 灵活控制路径、方法、头部等
  • 生产环境推荐方式

✅ 方法 3:通过 Filter 自定义 CORS(底层控制)

适用场景: 需要完全自定义 CORS 响应头,或与 Spring Security 集成

java 复制代码
@Component
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;

        // response.setHeader("Access-Control-Allow-Origin", "*");
        // 注意:没有 Allow-Credentials!
        
        response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");

        // 如果是预检请求(OPTIONS),直接返回
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }
}

⚠️ 注意:如果使用 Spring Security,需确保此 Filter 在 Security Filter 之前执行。

优点:

  • 完全控制响应头
  • 可处理复杂逻辑(如动态 origin)

缺点:

  • 代码较繁琐
  • 容易出错(如漏掉 OPTIONS 处理)

✅ 方法 4:在 application.yml / application.properties 中配置(仅限 Spring Boot 2.4+)

⚠️ 注意:Spring Boot 本身不支持通过配置文件直接开启 CORS! 但如果你使用 Spring Cloud Gateway 或 某些 starter,可能有扩展支持。

❌ 普通 Spring Boot Web 项目不能这样配置!

所以:不要尝试在 application.yml 里写 cors 配置(除非你用的是特定网关组件)。

场景 1:Spring WebFlux(响应式)项目

✅ application.yml

yaml 复制代码
spring:
  webflux:
    cors:
      allowed-origins: "*"
      allowed-methods: "GET,POST,PUT,DELETE,OPTIONS"
      allowed-headers: "*"
      max-age: 3600

场景 2:Spring Boot Actuator 端点的 CORS 配置

即使你用的是 Spring MVC,Actuator 的监控端点也支持通过配置文件开启 CORS:

✅ application.yml

yaml 复制代码
management:
  endpoints:
    web:
      cors:
        allowed-origins: "http://localhost:3000"
        allowed-methods: "*"
        allowed-headers: "*"
项目类型 是否支持 application.yml 配置 CORS 推荐方式
Spring MVCspring-boot-starter-web ❌ 不支持 使用 WebMvcConfigurer@CrossOrigin
Spring WebFluxspring-boot-starter-webflux ✅ 支持 spring.webflux.cors.*
Actuator 端点 ✅ 支持(仅限监控接口) management.endpoints.web.cors.*

✅ 方法 5:结合 Spring Security 配置 CORS(安全场景必备)

如果你的项目用了 Spring Security,必须显式启用 CORS,否则 Security 会拦截 OPTIONS 请求!

java 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .cors().and() // 👈 关键:启用 CORS 支持
            .csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .anyRequest().permitAll()
            );
        return http.build();
    }

    // 同时提供全局 CorsConfigurationSource
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

为什么需要?

  • Spring Security 默认不处理 CORS
  • 如果不配置,浏览器预检请求(OPTIONS)会被 Security 拦截 → 跨域失败

🚫 常见错误

问题 说明
allowedOrigins("*") + allowCredentials(true) 冲突 浏览器不允许:Access-Control-Allow-Origin* 时,不能带 cookie。必须指定具体 origin
忘记处理 OPTIONS 请求 预检请求失败,导致跨域报错
CORS 配置被 Security 覆盖 必须在 Spring Security 中显式启用 .cors(),否则 OPTIONS 请求会被拦截
生产环境使用 allowedOrigins("*") 存在安全风险,应明确指定可信的前端域名

✅ 最佳实践

场景 推荐方案
快速测试 / 小型项目 使用 @CrossOrigin 注解
标准 Web 项目(未集成 Spring Security) 实现 WebMvcConfigurer 进行全局 CORS 配置
项目已集成 Spring Security 在 Security 配置中调用 .cors(),并提供 CorsConfigurationSource Bean
需要动态 Origin(如多租户、白名单配置) 自定义 CorsFilter 实现灵活控制

一句话记住:

普通项目用 WebMvcConfigurer,带 Security 的项目必须在 Security 中 .cors() 并提供 CorsConfigurationSource。

相关推荐
颜酱2 分钟前
# 02 | 搭骨架:用 LangGraph 编排 12 步工作流(思路)
前端·人工智能·后端
颜酱3 分钟前
02 | 搭骨架:用 LangGraph 编排 12 步工作流
前端·人工智能·后端
嘉伟桑1 小时前
Python调用电价API返回JSON示例:分时电价、现货电价和字段解析
后端
武子康1 小时前
Shippy:确定性工具、会话级 Sandbox 与 Live-Data Eval(4 类收敛 + 7 步实现方案 + 6 类评测指标)
前端·人工智能·后端
我叫黑大帅2 小时前
我为什么单一消费者的场景下,要用 Redis List 当消息队列?
redis·后端·面试
AskHarries2 小时前
文件上传系统
后端
止语Lab3 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活3 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困3 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn3 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端