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("*")(浏览器安全限制),应指定具体域名
相关推荐
别来无恙1493 小时前
Spring Boot + ECharts 极简整合指南:从零实现动态数据可视化大屏
spring boot·信息可视化·echarts
刘火锅3 小时前
Bug 记录:SecureRandom.getInstanceStrong()导致验证码获取阻塞
spring boot·spring·spring cloud·bug
hrrrrb4 小时前
【Spring Boot 快速入门】八、登录认证(一)基础登录与认证校验
spring boot·后端
运维帮手大橙子4 小时前
完整的登陆学生管理系统(配置数据库)
java·前端·数据库·eclipse·intellij-idea
王大锤·4 小时前
基于spring boot的个人博客系统
java·spring boot·后端
bobz9655 小时前
QT designer 常用技巧
后端
shi57835 小时前
C# 常用的线程同步方式
开发语言·后端·c#
sg_knight5 小时前
Spring Cloud Gateway全栈实践:动态路由能力与WebFlux深度整合
java·spring boot·网关·spring·spring cloud·微服务·gateway
没逻辑5 小时前
抗量子密码技术(PQC)演变
后端·量子计算
JosieBook5 小时前
【IDEA】IntelliJ IDEA 中文官方文档全面介绍与总结
java·ide·intellij-idea