在 Spring Cloud Gateway 中实现跨域(CORS)的两种主要方式

在 Spring Cloud Gateway 中实现跨域(CORS)主要有 两种方式

  1. 通过配置类方式(推荐) - 使用 CorsWebFilter
  2. 通过配置文件方式(YAML/Properties)

🚀 推荐方式:使用 CorsWebFilter 配置类(更灵活、可控)

✅ 为什么推荐?

  • 精确控制跨域行为(路径、方法、Header 等)
  • 支持动态配置(如从数据库读取)
  • 与 Spring WebFlux 完全兼容(Gateway 基于 WebFlux)
  • 不依赖路由配置,全局生效或按需生效

📌 完整示例:使用 CorsWebFilter 实现跨域

第一步:创建跨域配置类

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

/**
 * Spring Cloud Gateway 跨域配置类
 * 
 * 说明:
 * - 本配置使用 CorsWebFilter 实现全局跨域支持
 * - 适用于 Spring Cloud Gateway 2020.0.0 及以上版本(基于 Spring WebFlux)
 * - 该 Filter 会在请求进入路由之前生效,确保 OPTIONS 预检请求被正确处理
 */
@Configuration(proxyBeanMethods = false)
public class CorsConfig {

    /**
     * 创建 CorsWebFilter Bean,用于处理跨域请求
     * 
     * @return 配置好的 CorsWebFilter 实例
     */
    @Bean
    public CorsWebFilter corsWebFilter() {
        // 1. 创建 CorsConfiguration 对象,用于定义跨域规则
        CorsConfiguration corsConfiguration = new CorsConfiguration();

        // 2. 允许的请求来源(Origin)
        // 注意:生产环境不要使用 "*",应明确指定可信域名
        corsConfiguration.addAllowedOriginPattern("*"); // Spring Boot 2.4+ 推荐使用 addAllowedOriginPattern 代替 addAllowedOrigin
        // 如果你使用的是较老版本(<2.4),请使用:corsConfiguration.addAllowedOrigin("*");

        // 3. 允许携带 Cookie(如果前端需要发送认证信息如 JWT Token)
        corsConfiguration.setAllowCredentials(true);

        // 4. 允许的 HTTP 方法
        corsConfiguration.addAllowedMethod("GET");
        corsConfiguration.addAllowedMethod("POST");
        corsConfiguration.addAllowedMethod("PUT");
        corsConfiguration.addAllowedMethod("DELETE");
        corsConfiguration.addAllowedMethod("OPTIONS");

        // 5. 允许的请求头(Header)
        // 常见的如 Content-Type, Authorization, X-Requested-With 等
        corsConfiguration.addAllowedHeader("*"); // 允许所有请求头(生产环境建议明确列出)

        // 6. 暴露给前端的响应头(可选)
        corsConfiguration.addExposedHeader("Authorization");
        corsConfiguration.addExposedHeader("Content-Disposition");

        // 7. 预检请求(OPTIONS)缓存时间(单位:秒)
        corsConfiguration.setMaxAge(3600L); // 1小时,减少预检请求次数

        // 8. 创建 UrlBasedCorsConfigurationSource,将 CORS 配置应用到所有路径
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration); // /** 表示匹配所有路径

        // 9. 返回 CorsWebFilter,Spring Gateway 会自动将其加入过滤器链
        return new CorsWebFilter(source);
    }
}

第二步:确保你的 application.yml 中没有冲突配置

yaml 复制代码
spring:
  cloud:
    gateway:
      # 路由配置示例(与跨域无关,仅为完整上下文)
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
  # 注意:不要在这里配置 globalcors(除非你选择配置文件方式)

⚠️ 重要提示 :如果你同时使用了 globalcors 配置和 CorsWebFilter,可能会导致冲突。建议只使用一种方式


🔁 替代方案:使用 application.yml 配置(简单但不够灵活)

如果你只需要简单跨域,也可以在 application.yml 中配置:

yaml 复制代码
spring:
  cloud:
    gateway:
      # CORS 跨域配置,CORS 是网关的责任,而不是业务服务的负担
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有路由路径(/** 表示所有 API 路径都应用此 CORS 规则)
            # 使用 allowed-origin-patterns 替代 allowedOrigins(支持通配符模式,更安全灵活)
            allowed-origin-patterns:
              - "http://localhost:*"      # 开发环境,允许本地开发环境(任意端口)发起跨域请求
              - "https://yourdomain.com"  # 生产环境,允许指定的生产域名访问
              - "https://*.yourcompany.com" # 允许 yourcompany.com 的所有子域名访问
            # 允许的 HTTP 请求方法(前端可以使用这些方法发起跨域请求)
            allowed-methods:
              - GET     # 允许获取资源(如查询用户信息、列表数据等)
              - POST    # 允许提交数据(如创建用户、提交表单等)
              - PUT     # 允许全量更新资源(如修改用户完整信息)
              - DELETE  # 允许删除资源(如删除订单、用户等)
              - OPTIONS # 允许预检请求(浏览器自动发送,用于 CORS 预检,必须包含!)
              - PATCH   # 允许部分更新资源(如只修改用户邮箱或昵称)
            # 允许客户端在跨域请求中携带的自定义请求头(Header)
            # 如果前端请求中包含未在此列出的 Header,浏览器会拦截并报 CORS 错误
            allowed-headers:
              - "Content-Type"       # 允许指定请求体的媒体类型(如 application/json)
              - "Authorization"      # 允许携带认证令牌(如 Bearer JWT Token)
              - "X-Requested-With"   # 常用于标识 AJAX 请求(部分前端框架自动添加)
              - "Accept"             # 允许客户端声明可接受的响应内容类型(如 application/json)
            # 是否允许跨域请求携带身份凭证(如 Cookie、Authorization Header)
            # 注意:当 allow-credentials 为 true 时,allowed-origin-patterns 不能为 "*"
            allow-credentials: true
            # 预检请求(OPTIONS)的缓存时间(单位:秒)
            # 浏览器在该时间内不会再发送 OPTIONS 请求,提升性能
            max-age: 3600  # 缓存 1 小时(3600 秒)

注意 :在最新版本的 Spring Cloud Gateway 中,spring.cloud.gateway.globalcors.cors-configurations 被标记为:弃用的配置属性,IDEA 提示推荐使用 spring.cloud.gateway.server.webflux.globalcors.cors-configurations

yaml 复制代码
spring:
  cloud:
    gateway:
      server:
        webflux:
          # CORS 跨域配置,CORS 是网关的责任,而不是业务服务的负担
          globalcors:
            cors-configurations:
              '[/**]': # 匹配所有路由路径(/** 表示所有 API 路径都应用此 CORS 规则)
                # 使用 allowed-origin-patterns 替代 allowedOrigins(支持通配符模式,更安全灵活)
                allowed-origin-patterns:
                  - "http://localhost:*"      # 开发环境,允许本地开发环境(任意端口)发起跨域请求
                  - "https://yourdomain.com"  # 生产环境,允许指定的生产域名访问
                  - "https://*.yourcompany.com" # 允许 yourcompany.com 的所有子域名访问
                # 允许的 HTTP 请求方法(前端可以使用这些方法发起跨域请求)
                allowed-methods:
                  - GET     # 允许获取资源(如查询用户信息、列表数据等)
                  - POST    # 允许提交数据(如创建用户、提交表单等)
                  - PUT     # 允许全量更新资源(如修改用户完整信息)
                  - DELETE  # 允许删除资源(如删除订单、用户等)
                  - OPTIONS # 允许预检请求(浏览器自动发送,用于 CORS 预检,必须包含!)
                  - PATCH   # 允许部分更新资源(如只修改用户邮箱或昵称)
                # 允许客户端在跨域请求中携带的自定义请求头(Header)
                # 如果前端请求中包含未在此列出的 Header,浏览器会拦截并报 CORS 错误
                allowed-headers:
                  - "Content-Type"       # 允许指定请求体的媒体类型(如 application/json)
                  - "Authorization"      # 允许携带认证令牌(如 Bearer JWT Token)
                  - "X-Requested-With"   # 常用于标识 AJAX 请求(部分前端框架自动添加)
                  - "Accept"             # 允许客户端声明可接受的响应内容类型(如 application/json)
                # 是否允许跨域请求携带身份凭证(如 Cookie、Authorization Header)
                # 注意:当 allow-credentials 为 true 时,allowed-origin-patterns 不能为 "*"
                allow-credentials: true
                # 预检请求(OPTIONS)的缓存时间(单位:秒)
                # 浏览器在该时间内不会再发送 OPTIONS 请求,提升性能
                max-age: 3600  # 缓存 1 小时(3600 秒)

注意 :YAML 方式在 Spring Cloud Gateway 2020.0.0+ 中仍然有效,但 无法处理复杂逻辑(如动态来源、条件判断等)。


🧪 测试跨域是否生效

你可以用前端代码测试:

javascript 复制代码
// 前端 JavaScript 测试(浏览器控制台)
fetch('http://localhost:8080/api/user/profile', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer your-token'
  },
  credentials: 'include' // 如果需要发送 Cookie
})
.then(res => res.json())
.then(data => console.log(data));

同时用 Postman 或 curl 发送 OPTIONS 请求验证:

bash 复制代码
curl -H "Origin: http://localhost:3000" \
     -H "Access-Control-Request-Method: POST" \
     -H "Access-Control-Request-Headers: Authorization" \
     -X OPTIONS http://localhost:8080/api/user/login

如果返回头中包含:

复制代码
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Credentials: true

说明跨域配置成功!


✅ 最佳实践建议

项目 建议
生产环境 Origin 不要使用 *,应明确列出可信域名,如 http://yourdomain.com
Allow Credentials 如果使用 JWT Token 放在 Header,可设为 true;若用 Cookie 认证,必须为 true
Allowed Headers 生产环境建议明确列出,如 Authorization, Content-Type, X-Requested-With
配置方式选择 优先使用 CorsWebFilter 配置类,便于维护和扩展

📚 总结

  • 推荐方式 :使用 @Configuration + CorsWebFilter(本文第一种方式)
  • 适用场景:所有 Spring Cloud Gateway 项目(2020.0.0+)
  • 优势:灵活、安全、可编程、与 WebFlux 完美集成

💡 提示:Spring Cloud Gateway 是响应式架构(基于 WebFlux),不要使用 Spring MVC 的 @CrossOriginWebMvcConfigurer,它们在 Gateway 中无效!

相关推荐
Controller-Inversion20 小时前
岛屿问题(dfs典型问题求解)
java·算法·深度优先
F***c32520 小时前
PHP在微服务中的分布式跟踪
分布式·微服务·php
okseekw20 小时前
Java 字符串三巨头:String、StringBuilder、StringJoiner —— 初学者避坑指南 🤯
java
q***064721 小时前
Spring Boot 从 2.7.x 升级到 3.3注意事项
数据库·hive·spring boot
毕设源码余学姐21 小时前
计算机毕设 java 中医药药材分类采购网站 SSM 框架药材交易平台 Java 开发的分类采购与订单管理系统
java·开发语言·课程设计
BD_Marathon21 小时前
【JUC】并发与并行
java
okseekw21 小时前
Java String类详解:不可变性、创建方式与比较方法
java
q***649721 小时前
Spring Boot 各种事务操作实战(自动回滚、手动回滚、部分回滚)
java·数据库·spring boot
降临-max21 小时前
JavaSE---网络编程
java·开发语言·网络·笔记·学习
带刺的坐椅1 天前
Solon AI 开发学习5 - chat - 支持哪些模型?及方言定制
java·ai·openai·solon