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

Angular对接Spring Boot网关时出现CORS错误求助

问题描述

直接调用服务控制器的注册接口时,运行正常,用户信息能保存且返回200响应;但通过网关调用同一接口时,用户信息虽能保存,但耗时极久,同时出现CORS错误,且响应状态码仍为200。

错误信息

signup:1 Access to fetch at 'http://localhost:8080/auth/register' from origin 'http://localhost:4200' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:4200, *', but only one is allowed. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

请求信息

  • 请求URL:http://localhost:8080/auth/register
  • 请求方法:POST
  • 状态码:200 OK
  • Referrer Policy:strict-origin-when-cross-origin

相关代码

网关后端配置(yml)

cloud:
  discovery:
    enabled: true
  gateway:
    globalcors:
      corsConfigurations:
        '[/**]':
          allowedOrigins: "http://localhost:4200"       # Allows requests from any origin
          allowedMethods: "GET,POST"       # Allows all HTTP methods (GET, POST, etc.)
          allowedHeaders: "*"       # Allows all headers

网关Filter代码

@Override
public GatewayFilter apply(Object config) {
    return ((exchange, chain) -> {
        if(validator.isSecured.test(exchange.getRequest()))
        {

            if(!exchange.getRequest().getHeaders().containsKey(HttpHeaders.AUTHORIZATION)){
                throw new TokenMissingException("Token is not present");
            }
            String authHeader= exchange.getRequest().getHeaders().get(HttpHeaders.AUTHORIZATION).get(0);
            if(authHeader!=null && authHeader.startsWith("Bearer ")) {
                authHeader=authHeader.substring(7);
            }
            try {
                    jwtValidation.validateToken(authHeader);
            }
            catch (Exception ex){
                    throw new TokenMissingException("Not authorized to access the request");
            }
        }
        return chain.filter(exchange);
    });
}

前端组件代码

export class SignupComponent implements OnInit{

  user : User = new User();

  constructor(private signupService: SignupService){}

  ngOnInit(): void {}
  
  registerUser(){
    console.log('User to register:', this.user);

    this.signupService.registerUser(this.user).subscribe(
      data =>  {  console.log("User  registered Successfully",data);
        alert("User is registered")
      },
      error => {
        console.error('Error registering user:', error);
        alert("User not registered")
      }
    )
  }

前端服务代码

const BASE_URL="http://localhost:8080/auth";


@Injectable({
  providedIn: 'root'
})

export class SignupService {

  constructor(private http : HttpClient) { }

  registerUser(user: User): Observable<Object>{
      return this.http.post(BASE_URL+"/register",user);
  }

}
解决方案

核心问题是网关和后端服务同时添加了CORS响应头,导致Access-Control-Allow-Origin出现多个值(http://localhost:4200和*),浏览器判定为非法。

解决步骤:

  1. 移除后端服务的CORS配置:找到注册接口所在的服务,删除其中的CORS相关配置(比如@CrossOrigin注解、全局CORS配置类),让网关统一处理跨域逻辑。
  2. 确认网关CORS配置生效:当前网关yml的全局CORS配置已经正确指定了允许的源,无需修改,但要确保自定义Filter没有覆盖或干扰网关的CORS响应头设置。
  3. 耗时问题自动解决:之前的请求耗时久是因为浏览器在检测到CORS错误后,仍会等待后端请求完成,同时前端进入错误回调。解决重复响应头问题后,请求耗时会恢复正常。

额外注意:

  • 禁止同时在网关和后端服务配置CORS,否则必然导致响应头冲突。
  • 如果后端服务需要被非网关请求直接调用,可以在后端配置CORS时,仅允许网关地址访问,或者通过请求头动态判断是否添加CORS头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:02:09