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("*")(浏览器安全限制),应指定具体域名
相关推荐
Q_Q51100828510 分钟前
python+django/flask的车辆尾气检测排放系统-可视化大屏展示
spring boot·python·django·flask·node.js·php
汤姆yu28 分钟前
基于SpringBoot的动漫周边商场系统的设计与开发
java·spring boot·后端
皮皮林55132 分钟前
快速解决 Maven 版本冲突指南 !
java·maven
灰小猿43 分钟前
Spring前后端分离项目时间格式转换问题全局配置解决
java·前端·后端·spring·spring cloud
算法与编程之美1 小时前
理解Java finalize函数
java·开发语言·jvm·算法
怕什么真理无穷1 小时前
C++面试4-线程同步
java·c++·面试
lkbhua莱克瓦241 小时前
Java基础——常用算法5
java·开发语言·笔记·github
牢七1 小时前
javan小案例。
java
星释2 小时前
Rust 练习册 :Luhn与校验算法
java·算法·rust
RedJACK~2 小时前
Go Ebiten小游戏开发:扫雷
开发语言·后端·golang