You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot网关配置CorsWebFilter报Access-Control-Allow-Origin多源错误求助

问题根因

你遇到的两次报错均为跨域配置的典型问题:

  1. 最初的Access Control Origin header not present是因为网关没有配置跨域策略,浏览器跨域请求被拦截
  2. 后续的Access-Control-Allow-Origin cannot contain more than one origin是因为响应中出现了重复的Access-Control-Allow-Origin响应头,不符合浏览器CORS规范。Postman不会校验CORS规则,所以请求正常。

解决方案

1. 修正CORS配置类

Spring Boot 2.4+版本后,直接使用addAllowedOrigin("*")在请求带认证凭证时会触发规则冲突,替换为setAllowedOriginPatterns兼容场景:

import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.cors.reactive.CorsWebFilter;

@Configuration
public class CorsConfig {

    @Bean
    public CorsWebFilter corsWebFilter() {
        final CorsConfiguration corsConfig = new CorsConfiguration();
        corsConfig.setMaxAge(3600L);
        // 替换原addAllowedOrigin("*"),兼容带认证信息的跨域请求
        corsConfig.setAllowedOriginPatterns(Collections.singletonList("*"));
        corsConfig.addAllowedHeader("*");
        // 开启跨域凭证传递,适配前端带Authorization头的请求场景
        corsConfig.setAllowCredentials(true);
        corsConfig.addAllowedMethod("OPTIONS");
        corsConfig.addAllowedMethod("HEAD");
        corsConfig.addAllowedMethod("GET");
        corsConfig.addAllowedMethod("PUT");
        corsConfig.addAllowedMethod("POST");
        corsConfig.addAllowedMethod("DELETE");
        corsConfig.addAllowedMethod("PATCH");
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig);
        return new CorsWebFilter(source);
    }
}

2. 网关路由添加响应头去重配置

在所有路由的过滤器中添加CORS响应头去重规则,避免多链路写入重复头:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    String authorizationValue = getAuthorization();
    return builder.routes()
            .route("auth-service", r -> r.path("/auth-service/**")
                    .filters(f -> f.filter(filter)
                            // 新增CORS响应头去重,保留第一个出现的有效值
                            .dedupeResponseHeader("Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Allow-Headers", "RETAIN_FIRST"))
                    .uri("lb://auth-service"))
            .route("currency-exchange", r -> r.path("/currency-exchange/**")
                    .filters(f -> f.filter(filter)
                            .addRequestHeader(authorizationKey, authorizationValue)
                            .dedupeResponseHeader("Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Allow-Headers", "RETAIN_FIRST"))
                    .uri("lb://currency-exchange"))
            .route("currency-conversion", r -> r.path("/currency-conversion/**")
                    .filters(f -> f.filter(filter)
                            .addRequestHeader(authorizationKey, authorizationValue)
                            .dedupeResponseHeader("Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Allow-Headers", "RETAIN_FIRST"))
                    .uri("lb://currency-conversion"))
            .route("hindu-religious", r -> r.path("/hindu-religious/image/**")
                    .filters(f -> f.addRequestHeader(authorizationKey, authorizationValue)
                            .dedupeResponseHeader("Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Allow-Headers", "RETAIN_FIRST"))
                    .uri("lb://hindu-religious"))
            .route("hindu-religious", r -> r.path("/hindu-religious/**")
                    .filters(f -> f.filter(filter)
                            .addRequestHeader(authorizationKey, authorizationValue)
                            .dedupeResponseHeader("Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Allow-Headers", "RETAIN_FIRST"))
                    .uri("lb://hindu-religious"))
            .build();
}

3. 排查重复配置

  • 确认项目配置文件(application.yml/application.properties)中没有spring.cloud.gateway.globalcors相关配置,避免和代码中的CorsWebFilter重复生效
  • 再次确认下游微服务没有配置任何CORS相关过滤器、跨域适配逻辑,防止下游写入CORS头和网关配置叠加

内容的提问来源于stack exchange,提问作者AMIT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 18:36:06