Spring Boot部署HTTPS后Stomp WebSocket握手失败提示Upgrade头为null
核心结论
你不需要使用代理服务器,当前报错和代理无关,是HTTPS场景下的内置容器配置、WebSocket端点配置缺失导致的。
错误根因
WebSocket握手阶段要求请求必须携带两个核心头:Upgrade: websocket 和 Connection: Upgrade,服务端校验通过后才能完成握手切换到WebSocket协议。你看到的Upgrade header: null报错,说明服务端没有收到这个必要请求头,握手直接失败。
本地HTTP环境运行正常,是因为Spring Boot内置容器(默认Tomcat)对HTTP协议的WebSocket头默认做了适配;HTTPS环境下默认配置未开启对应的请求头解析逻辑,导致头被丢弃,就出现了这个报错。
很多同类问题出现在代理场景是因为Nginx/Apache等代理默认不会转发WebSocket的Upgrade头,需要手动配置,但你没有使用代理的情况下,问题完全出在服务端本身的配置,不需要额外部署代理服务。
解决步骤
- 第一步:修改WebSocket端点配置,补充跨域和协议适配
调整WebSocketConfig类配置如下:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws") // 生产环境请替换为你的实际域名,不要直接用* .setAllowedOrigins("*") .withSockJS(); } }
- 第二步:配置内置Tomcat的HTTPS头解析规则
新增Tomcat配置类,开启请求协议识别,确保WebSocket的握手头不会被丢弃:
import org.apache.catalina.valves.RemoteIpValve; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TomcatConfig { @Bean public TomcatServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); tomcat.addContextValves(new RemoteIpValve(){{ setProtocolHeader("X-Forwarded-Proto"); setProtocolHeaderHttpsValue("https"); }}); return tomcat; } }
- 第三步:确认HTTPS配置正确
检查application.yml/application.properties中的SSL证书配置无误,没有端口冲突:
server: port: 443 ssl: key-store: classpath:你的证书文件.p12 key-store-password: 你的证书密码 keyStoreType: PKCS12
如果配置完成后仍然报错,可以临时增加握手拦截器打印请求头,排查是否有其他安全规则过滤了请求头:
registry.addEndpoint("/ws") .setAllowedOrigins("*") .addInterceptors(new HandshakeInterceptor() { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { // 打印所有请求头,确认Upgrade是否存在 request.getHeaders().forEach((k,v) -> System.out.println(k + ":" + v)); return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { } }) .withSockJS();
内容的提问来源于stack exchange,提问作者Vishal_Kotecha
相关产品推荐
相关产品推荐

