开发者

SpringBoot解决跨域的五种方式

目录
  • 方法 1:使用 @CrossOrigin 注php解(最简单)
    • 优点:
    • 缺点:
  • 方法 2:全局配置 CORS(推荐!)
    • 方式 A:实现 WebMvcConfigurer 接口(Spring Boot 2.x+)
    • 方式 B:使用 @Bean 注册 CorsConfigurationSource
    • 优点:
  • 方法 3:通过 Filter 自定义 CORS(底层控制)
    • 优点:
    • 缺点:
    • 场景 1:Spring WebFlux(响应式)项目
    • 场景 2:Spring Boot Actuator 端点的 CORS 配置
  • 方法 4:结合 Spring Security 配置 CORS(安全场景必备)
    • 常见错误
      • 最佳实践
        • 一句话记住:

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

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

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

          @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+)

          @Configuration
          public class CorsConfig implements WebMvcConfigurer {
          
              @Override
              public void aTeLeVvrCddCorsMappings(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

          @Configuration
          public class CorsConfig {
          
              @Bean
              public CorsConfigurationSource corsConfigurationSource()www.devze.com {php
                  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); // ⚠️ 不能与 "*" 同时使用!
          
                  UrlBasedCorsConfigurationSo编程urce source = new UrlBasedCorsConfigurationSource();
                  source.registerCorsConfiguration("/**", config);
                  return source;
              }
          }
          

          优点:

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

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

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

          @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

          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

          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.*

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

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

          @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。

          以上就是SpringBoot解决跨域的五种方式的详细内容,更多关于SpringBoot解决跨域的资料请关注编程客栈(www.devze.com)其它相关文章!

          0

          上一篇:

          下一篇:

          精彩评论

          暂无评论...
          验证码 换一张
          取 消

          最新开发

          开发排行榜