跳转到内容

Node 放在 IIS/Nginx 后面:WebSocket、SSE 与代理超时

核验于 1 分钟阅读

反代 Node 时正确转发 Host/X-Forwarded,支持 WebSocket 升级、SSE 不缓冲,并设置不会切断长连接的超时。

测试环境Standard / Datacenter · 版本号 26100.33650 · x64
E1
版本号
26100.33650
版本
Standard / Datacenter
架构
x64
支持
文档(E1)
证据
E1官方文档
核验日期
2026-10-29
页面类型
任务

Node 监听 127.0.0.1:3000,IIS ARR 或 Nginx 占 443。代理必须:

  • 保留 Host;
  • 发 X-Forwarded-For/X-Forwarded-Proto;
  • 允许 WebSocket 升级;
  • 不缓冲 SSE;
  • 读超时长于最慢合法连接。
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
}

WebSocket:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;

SSE:

proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;

没有 proxy_buffering off,事件可能成批到,或连接关闭才到。

  • 农场指向 127.0.0.1:3000。
  • 保留 Host,转发 XFF/XFP。
  • 应用用 WebSocket 就在 ARR/农场设置里启用。
  • 设代理超时;不要全局关。
app.set('trust proxy', 1);

只在应用位于可信代理后面时设置。之后 req.ip、req.protocol、secure cookie 才正确。Node 直接暴露时设 trust proxy,客户端就能伪造 X-Forwarded-*。

  • Node 的 keepAliveTimeout 应大于代理空闲超时,否则代理可能复用应用刚关的 socket。
  • 代理 proxy_read_timeout 大于最长响应。
  • SSE/WebSocket 长读超时是预期;普通 API 保持短。
终端窗口
curl.exe -I https://app.example/
curl.exe -N https://app.example/events
Get-Content C:\logs\api-a\out.log -Tail 50

应用看到公网 host/proto,SSE 增量到达,WebSocket 升级返回 101。

E1。实验室把 Nginx 跑在 8081,但没有反代 Node 应用;配置是 Server 2025 上待验证的方案。

来源