React.js无法连接Spring Boot WebSocket,Postman可正常连接求排查
问题分析与解决方案
问题场景
搭建了Spring Boot WebSocket服务,Postman可正常连接并接收消息,但运行在http://localhost:3000的React应用连接时返回403 Forbidden,连接未建立即关闭,服务器无相关日志输出。
核心原因
Postman发起WebSocket连接时不会携带浏览器级别的Origin请求头(或Origin为Postman自身域名),而React前端页面会自动携带Origin: http://localhost:3000请求头。Spring Boot默认WebSocket配置未允许该跨域Origin,导致握手阶段被拦截,返回403。
解决方案
1. 配置WebSocket允许跨域Origin
修改WebSocketConfigurer实现,在注册Handler时添加跨域允许配置:
@Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new ServerWebSocketHandler(), "/socket") // 允许React服务的Origin跨域请求 .setAllowedOrigins("http://localhost:3000") // 若需支持多个Origin或通配符(生产环境不建议用*),可使用以下方式(Spring Boot 2.4+支持) // .setAllowedOriginPatterns("http://localhost:*"); }
2. 集成Spring Security时的额外配置
如果项目引入了Spring Security,需在Security配置中允许WebSocket路径的HTTP握手请求,并放行CORS预检的OPTIONS请求:
@Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth // 允许WebSocket路径的匿名访问 .requestMatchers("/socket").permitAll() .anyRequest().authenticated() ) // WebSocket握手阶段无需CSRF校验,按需禁用或配置 .csrf(csrf -> csrf.disable()) .headers(headers -> headers .frameOptions(frame -> frame.sameOrigin()) ); return http.build(); } }
3. 前端代码小优化(可选)
服务器发送的初始消息是纯文本而非JSON格式,直接用JSON.parse会报错,可调整前端消息处理逻辑:
ws.current.onmessage = e => { console.log("收到服务器消息:", e.data); // 若后续服务器发送JSON格式数据,再启用以下解析逻辑 // try { // const message = JSON.parse(e.data); // console.log("解析后的消息:", message); // } catch (err) { // console.log("非JSON格式消息:", e.data); // } };
内容的提问来源于stack exchange,提问作者Nicktar
相关产品推荐
相关产品推荐

