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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:39:03