发布时间: 2026年10月1日更新时间: 2026年10月1日

http-proxy-middleware WebSocket 配置与升级失败排查

http-proxy-middleware WebSocket 配置与升级失败排查,提供 Node.js 示例、Upgrade 检查和 407/502/504 排障步骤。

普通 HTTP 请求能成功,不代表 WebSocket 一定能升级。先让 Node.js 服务通过代理 IP 访问目标,再检查 Upgrade、超时、TLS 和服务端 upgrade 事件。

http-proxy-middleware 的 HTTP 与 WebSocket 转发边界

普通请求完成一次响应即可结束;WebSocket 则需要客户端发起 Upgrade、中间件转发握手、目标服务返回 101,并持续保持双向连接。任何一层未处理 Upgrade,都可能出现“网页请求正常、WebSocket 失败”。

普通 HTTP 代理请求和 WebSocket Upgrade 是两条不同链路;ws: true 只表示中间件允许升级,不代表目标服务、代理 IP 和超时配置已经兼容。

Node.js 中间件配置与 101 握手验证

createProxyMiddleware 的反向转发不等于额外出站代理。若目标链路还需要代理 IP,应从环境变量读取代理 URL,并传入与目标协议匹配的 Agent;否则本文只讨论反向转发,不应暗示已自动使用指定代理出口。

```js
import http from 'node:http';
import { createProxyMiddleware } from 'http-proxy-middleware';
import { HttpsProxyAgent } from 'https-proxy-agent';

const outboundAgent = new HttpsProxyAgent(process.env.PROXY_URL);

const app = createProxyMiddleware({
target: 'https://target.example.com',
changeOrigin: true,
ws: true,
agent: outboundAgent,
proxyTimeout: 15000,
on: {
error(err, req) {
console.error('proxy error', req.url, err.message);
},
},
});

const server = http.createServer((req, res) => app(req, res));
server.on('upgrade', (req, socket, head) => app.upgrade(req, socket, head));
server.listen(3000);
```

这里的 ws: true 允许 WebSocket 转发,proxyTimeout 控制上游等待时间,upgrade 事件负责把升级请求交给中间件。成功测试不应只看 101,还要确认客户端可以收发消息,并记录连接关闭代码与原因。

示例按 http-proxy-middleware v3 的 on.error 事件结构编写;旧版本可能仍使用 onError,发布前应按项目锁定版本核对。

实际项目还要确认代理 IP 的协议、主机、端口和认证方式由客户端或上游连接层正确读取。不要把 WebSocket 的 Upgrade 头当作代理协议。

如何验证 101 Switching Protocols

1. 先用同一代理参数请求普通 HTTP URL,确认出口 IP 和状态码。
2. 再发起 WebSocket 握手,检查请求是否包含 Connection: Upgrade 和 Upgrade: websocket。
3. 407 查代理认证;400/401 查目标握手和权限;502/504 查 Node、中间代理和目标服务日志。
4. 连接建立后立即断开,重点检查 proxyTimeout、目标服务关闭策略和反向代理缓冲。
5. 固定 URL、代理 IP、客户端版本和超时参数,一次只改一个变量。

407、400、502、504 和连接断开怎么排查

按客户端、中间件、代理 IP 和目标服务四层查看日志,一次只修改协议、认证、Upgrade、超时或目标路径中的一个变量。

表现优先检查
407代理主机、端口和认证
400/401Upgrade 参数、目标路径或目标权限
502/504中间件、上游连接和超时
建立后立即关闭心跳、读取超时和目标服务关闭策略

代理 IP 应配置在哪一层

代理 IP应由实际发起上游连接的客户端或连接 Agent 读取,不能只在浏览器端配置后假定 Node.js 服务也会继承。

官方文档

http-proxy-middleware 的事件 API 可能随主版本变化,运行前应核对:

FAQ

为什么普通请求成功,WebSocket 仍失败?

普通请求只证明网络连通,WebSocket 还需要完成 Upgrade 握手、双向消息收发和长连接保持。

返回 101 后连接立即断开怎么办?

101 只证明握手完成。继续检查心跳、读取超时、目标服务关闭策略,以及客户端记录的关闭代码和原因。

验证顺序应是普通 HTTP → 101 握手 → 消息收发 → 长连接保持。代理认证或端口仍不确定时,可先使用智能检测助手。