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

如何阻止Tomcat发送Connection: close响应头?

解决Tomcat Websocket HTTPS下Connection头重复导致Safari断开问题

我之前也碰到过类似的坑!你的问题是Tomcat在HTTPS连接处理Websocket握手时,响应头里同时返回了Connection: upgrade和Connection: close,这会让Safari判定连接异常直接断开,而HTTP连接正常是因为HTTP场景下Tomcat的处理逻辑没问题。下面给你几个靠谱的解决方法:

方法一:改用NIO协议的Connector(最推荐)

你当前HTTPS Connector用的是旧的阻塞IO协议org.apache.coyote.http11.Http11Protocol,这个协议在处理Websocket的HTTPS握手时容易出现头重复的问题。换成非阻塞的NIO协议就能解决:

修改你的HTTPS Connector配置如下:

<Connector port="8443" 
           protocol="org.apache.coyote.http11.Http11NioProtocol" 
           maxThreads="150" 
           SSLEnabled="true" 
           scheme="https" 
           secure="true" 
           clientAuth="false" 
           sslProtocol="TLS" 
           keystoreFile="你的密钥库路径" 
           keystorePass="你的密钥库密码"
           connectionTimeout="20000"
           disableUploadTimeout="true" />
  • Http11NioProtocol是Tomcat推荐的现代非阻塞IO协议,对Websocket的支持更完善,不会错误添加Connection: close头
  • 补充connectionTimeout和disableUploadTimeout是为了和HTTP Connector的配置保持一致,避免额外的兼容性问题

方法二:添加自定义过滤器移除多余头(备选)

如果改协议后还是有问题,可以通过过滤器手动修正响应头:

首先创建一个过滤器类:

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ConnectionHeaderFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        chain.doFilter(request, response);
        // 检查并修正Connection头
        String connectionHeader = httpResponse.getHeader("Connection");
        if (connectionHeader != null && connectionHeader.contains("close") && connectionHeader.contains("upgrade")) {
            httpResponse.setHeader("Connection", "upgrade");
        }
    }

    @Override
    public void destroy() {}
}

然后在web.xml里配置这个过滤器,让它作用在你的Websocket端点上:

<filter>
    <filter-name>ConnectionHeaderFilter</filter-name>
    <filter-class>com.yourpackage.ConnectionHeaderFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ConnectionHeaderFilter</filter-name>
    <url-pattern>/你的Websocket端点路径/*</url-pattern>
</filter-mapping>

这个过滤器会在响应发送前检查Connection头,如果同时包含upgrade和close,就把它替换成只保留upgrade,从根源上解决Safari的断开问题。

方法三:升级Tomcat版本(兜底)

如果你的Tomcat版本比较旧(比如Tomcat 7或更早),这个问题可能是Tomcat的已知bug,升级到Tomcat 8.5或Tomcat 9以上的稳定版本,官方已经修复了这类Websocket握手的头处理问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:47:58