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

Angular中RxJS WebSocket遇302错误,如何获取错误码与重定向URL?

解决Angular WebSocket连接302重定向无法获取错误码及跳转的问题

问题根源

浏览器的WebSocket API出于安全限制,在握手失败(如返回302)时,不会将响应状态码、重定向URL等细节暴露给JavaScript,这就是你用rxjs webSocket 无法获取err.status和重定向地址的核心原因。

解决方案

先通过HTTP请求预检测WebSocket端点的状态(因为WebSocket握手基于HTTP协议),HTTP请求可以完整获取响应状态码和响应头,再根据结果处理:

1. 修改AppComponent代码

注入Angular的HttpClient,先发起HTTP GET请求检测端点,再建立WebSocket连接:

import { Component, OnInit } from '@angular/core';
import { webSocket } from 'rxjs/webSocket';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  private webSocketSubject$;

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    // 先通过HTTP请求检测WebSocket端点状态
    this.http.get('http://localhost:9090/secured-websocket', {
      observe: 'response', // 完整获取响应对象
      responseType: 'text' // 避免解析非JSON响应报错
    }).subscribe({
      next: (resp) => {
        // 返回101表示协议可切换,正常建立WebSocket连接
        if (resp.status === 101) {
          this.initWebSocket();
        }
      },
      error: (err) => {
        // 捕获HTTP错误响应
        if (err.status === 302) {
          // 获取重定向URL并跳转至Keycloak登录页
          const redirectUrl = err.headers.get('Location');
          if (redirectUrl) {
            window.location.href = redirectUrl;
          }
        } else {
          console.error('WebSocket端点检测失败:', err);
        }
      }
    });
  }

  private initWebSocket(): void {
    this.webSocketSubject$ = webSocket('ws://localhost:9090/secured-websocket');
    this.webSocketSubject$.asObservable().subscribe({
      next: (v) => console.log(v),
      error: (err) => console.log('WebSocket连接错误:', err),
      complete: () => console.log('WebSocket连接已关闭')
    });
  }
}

2. 后端CORS配置注意事项

确保后端Spring Boot配置了允许前端访问该WebSocket端点的CORS规则,否则HTTP预检测请求会被浏览器拦截。示例Spring Security CORS配置:

@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsWebFilter() {
        CorsConfiguration corsConfig = new CorsConfiguration();
        corsConfig.addAllowedOrigin("http://localhost:4200"); // 替换为你的Angular项目端口
        corsConfig.addAllowedMethod("*");
        corsConfig.addAllowedHeader("*");
        corsConfig.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/secured-websocket", corsConfig);

        return new CorsWebFilter(source);
    }
}

关键说明

  • 用HTTP请求预检测是绕开WebSocket API限制的唯一可行方式,HTTP请求能完整获取响应状态和头信息
  • 用户在Keycloak登录完成后,需在登录回调逻辑中重新调用initWebSocket()建立连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:57:56