Spring Boot 解决跨域问题

在 Spring Boot 中解决跨域问题(CORS)主要有三种常用方式,下面详细说明每种实现方法:

方案一:全局配置(推荐)

在配置类中实现 WebMvcConfigurer 接口,统一配置所有接口的跨域规则:

java 复制代码
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 CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 所有接口
                // Spring Boot 2.4+ 使用 allowedOriginPatterns
                .allowedOriginPatterns("*") 
                // 允许的请求方法
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") 
                // 允许的请求头
                .allowedHeaders("*") 
                // 是否允许发送Cookie
                .allowCredentials(true) 
                // 预检请求缓存时间(秒)
                .maxAge(3600); 
    }
}

方案二:控制器注解配置

在单个控制器或方法上使用 @CrossOrigin 注解:

java 复制代码
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
// 类级别配置(整个控制器生效)
@CrossOrigin(origins = "http://localhost:8080", allowCredentials = "true")
public class UserController {

    // 方法级别配置(覆盖类配置)
    @GetMapping("/users")
    @CrossOrigin(maxAge = 1800)
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
}

方案三:过滤器配置(适合WebFlux或特殊需求)

创建自定义CORS过滤器:

java 复制代码
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 GlobalCorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        
        // 允许所有域名(生产环境建议指定具体域名)
        config.addAllowedOriginPattern("*");
        // 允许发送Cookie
        config.setAllowCredentials(true);
        // 允许所有请求头
        config.addAllowedHeader("*");
        // 允许所有方法
        config.addAllowedMethod("*");
        // 预检请求缓存时间
        config.setMaxAge(3600L);

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

常见问题解决方案

  1. Credentials 与 Origin 冲突问题

    • 现象:前端携带 Cookie 时报错

    • 解决:

      java 复制代码
      // 正确配置
      .allowCredentials(true)
      // 使用 allowedOriginPatterns 替代 allowedOrigins
      .allowedOriginPatterns("http://trusted-domain.com") 
    • 前端配合:

      javascript 复制代码
      fetch(url, {
        credentials: 'include' // 必须
      })
  2. Spring Security 集成问题

    在 Security 配置中启用 CORS:

    java 复制代码
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors() // 启用 CORS
            .and()
            // ... 其他安全配置
    }
  3. OPTIONS 请求被拦截

    • 确保未手动拦截 OPTIONS 方法

    • 在 Security 配置中添加:

      java 复制代码
      .antMatchers(HttpMethod.OPTIONS).permitAll()
  4. 多配置冲突

    • 优先级:过滤器 > 全局配置 > @CrossOrigin
    • 建议整个项目统一使用一种配置方式

最佳实践建议

  1. 开发环境

    使用全局配置 + allowedOriginPatterns("*") 快速开发

  2. 生产环境

    java 复制代码
    .allowedOriginPatterns(
        "https://your-domain.com",
        "https://api.your-domain.com"
    )
  3. 安全加固

    java 复制代码
    // 限制允许的请求头
    .allowedHeaders("Content-Type", "X-Requested-With", "Authorization")
    // 暴露特定响应头
    .exposedHeaders("Custom-Header")

重要提示

  • Spring Boot 2.4.x+ 必须使用 allowedOriginPatterns 替代旧版 allowedOrigins
  • 开启 allowCredentials(true) 时,禁止使用 allowedOriginPatterns("*")(浏览器安全限制),应指定具体域名
相关推荐
老神在在0011 小时前
SpringMVC1
java·前端·学习·spring
程序猿小D2 小时前
[附源码+数据库+毕业论文+开题报告]基于Spring+MyBatis+MySQL+Maven+jsp实现的车辆运输管理系统,推荐!
java·数据库·mysql·spring·毕业设计·开题报告·车辆运输管理系统
Bug退退退1233 小时前
RabbitMQ 高级特性之消息分发
java·分布式·spring·rabbitmq
Jack_hrx4 小时前
基于 Drools 的规则引擎性能调优实践:架构、缓存与编译优化全解析
java·性能优化·规则引擎·drools·规则编译
二进制person5 小时前
数据结构--准备知识
java·开发语言·数据结构
半梦半醒*5 小时前
H3CNE综合实验之机器人
java·开发语言·网络
paopaokaka_luck5 小时前
基于SpringBoot+Uniapp球场预约小程序(腾讯地图API、Echarts图形化分析、二维码识别)
spring boot·小程序·uni-app
消失的旧时光-19435 小时前
Android模块化架构:基于依赖注入和服务定位器的解耦方案
android·java·架构·kotlin
洛_尘6 小时前
Java EE进阶2:前端 HTML+CSS+JavaScript
java·前端·java-ee