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("*")(浏览器安全限制),应指定具体域名
相关推荐
老华带你飞2 分钟前
个人网盘管理|基于springboot + vue个人网盘管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
宸津-代码粉碎机3 分钟前
告别繁琐SQL!MyBatis - Flex让数据库操作“飞”起来
java·服务器·tomcat
九转苍翎3 分钟前
Java外功核心(7)——深入源码,拆解Spring Bean作用域、生命周期与自动装配
spring boot
艾莉丝努力练剑10 分钟前
【Linux进程(四)】深入理解 Linux O(1) 调度器:双队列轮转与进程优先级机制——如何避免进程饥饿,实现公平且高效的进程调度
java·大数据·linux·运维·服务器·人工智能·安全
JaguarJack13 分钟前
PHP 之高级面向对象编程 深入理解设计模式、原则与性能优化
后端·php
郑州光合科技余经理1 小时前
PHP构建:支撑欧美澳市场的同城生活服务平台开发
java·开发语言·数据库·uni-app·php·排序算法·生活
章豪Mrrey nical8 小时前
前后端分离工作详解Detailed Explanation of Frontend-Backend Separation Work
后端·前端框架·状态模式
超级大只老咪8 小时前
数组相邻元素比较的循环条件(Java竞赛考点)
java
小浣熊熊熊熊熊熊熊丶8 小时前
《Effective Java》第25条:限制源文件为单个顶级类
java·开发语言·effective java
毕设源码-钟学长9 小时前
【开题答辩全过程】以 公交管理系统为例,包含答辩的问题和答案
java·eclipse