必须关闭 proxy_buffering 并配置 proxy_cache off、proxy_read_timeout 86400、chunked_transfer_encoding on 等参数,才能保障 Nginx 正确透传 SSE 流式响应;后端需返回 text/event-stream 类型与 keep-alive 头,前端需支持自动重连与断点续传。

要让 Nginx 正确透传后端的 SSE 流式响应,必须关闭 proxy_buffering——这不是可选项,而是保障实时性的硬性前提。默认开启时,Nginx 会把后端逐条输出的 data: xxx\n\n 拦在内存里攒着,等缓冲区满(默认约 8–128KB)或连接关闭才发给浏览器,导致前端收到的不是“一条一条”,而是“几秒一坨”,完全破坏 SSE 的流式语义。
为什么只写 proxy_buffering off 还不够
单独关闭缓冲只是第一步。Nginx 在流式场景下还有多个机制会“二次拦截”数据:
- proxy_cache on:可能尝试缓存整个长连接响应,造成截断或返回陈旧事件
- proxy_read_timeout 默认 60s:SSE 连接常空闲数分钟,超时会主动断连,触发前端频繁重连
- HTTP/1.0 或 Connection 头残留:中间设备可能误判为短连接而中断流
- 缺少 chunked_transfer_encoding:Nginx 可能试图计算不存在的 Content-Length,导致阻塞
SSE 路径专属的最小可行配置
将以下配置写在精确匹配 SSE 接口的 location 块中(例如 location /api/events { ... }),不推荐全局关闭:
proxy_buffering off;proxy_cache off;-
proxy_read_timeout 86400;(24 小时,远大于客户端重连间隔) proxy_send_timeout 86400;proxy_http_version 1.1;-
proxy_set_header Connection "";(清空 Connection 头,防代理误关) chunked_transfer_encoding on;-
add_header X-Accel-Buffering no;(显式告知客户端无缓冲)
注意:不要加 Upgrade 和 Connection upgrade,那是 WebSocket 用的,SSE 不需要。
后端与客户端协同要点
Nginx 配置只是链路一环,还需前后端配合:
-
后端必须返回正确响应头:
Content-Type: text/event-stream、Cache-Control: no-cache、Connection: keep-alive;若漏了,可在 Nginx 中兜底加add_header Content-Type "text/event-stream"; -
Go 客户端要禁用压缩:
http.Transport{DisableCompression: true},否则 gzip 会再次缓冲流 -
前端 EventSource 或 fetch + ReadableStream需处理自动重连,并用
id:字段支持断点续传,避免重复或丢事件
验证是否生效的简单方法
不用抓包也能快速判断:
- 打开浏览器开发者工具 → Network → 找到 SSE 请求 → 查看「Response」标签页:应持续滚动新内容,而非静止几秒后突然刷出一大段
- 检查响应头中是否有
X-Accel-Buffering: no - 用
curl -N http://your-domain.com/api/events(-N禁用 curl 自身缓冲),观察是否逐行即时输出
配置到位后,后端每输出一行 data: hello\n\n,前端 onmessage 几乎立刻触发,延迟可压至毫秒级。


















