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和*),浏览器判定为非法。
解决步骤:
- 移除后端服务的CORS配置:找到注册接口所在的服务,删除其中的CORS相关配置(比如
@CrossOrigin注解、全局CORS配置类),让网关统一处理跨域逻辑。 - 确认网关CORS配置生效:当前网关yml的全局CORS配置已经正确指定了允许的源,无需修改,但要确保自定义Filter没有覆盖或干扰网关的CORS响应头设置。
- 耗时问题自动解决:之前的请求耗时久是因为浏览器在检测到CORS错误后,仍会等待后端请求完成,同时前端进入错误回调。解决重复响应头问题后,请求耗时会恢复正常。
额外注意:
- 禁止同时在网关和后端服务配置CORS,否则必然导致响应头冲突。
- 如果后端服务需要被非网关请求直接调用,可以在后端配置CORS时,仅允许网关地址访问,或者通过请求头动态判断是否添加CORS头。
内容的提问来源于stack exchange,提问作者avar mittal
相关产品推荐
相关产品推荐

