在对接大模型问答的场景中,SSE(Server-Sent Events)是前端实现服务器单向推送的轻量方案。但在 React 项目中通过 Nginx 代理集成 SSE 时,很多开发者会遇到核心问题:后端逐字推送的流式数据,前端却 "分段卡顿" 批量显示,严重破坏实时交互体验。本文从问题背景、现象、解决方案三个维度,拆解 Nginx 关键配置的作用,帮助快速落地优化。
一、问题背景:为什么会出现 SSE 流式卡顿?
SSE 的核心特性是 "长连接 + 实时透传":基于 HTTP 长连接,服务器产生的每一段数据(哪怕一个字符)都需立即推送至客户端,依赖 HTTP 1.1 的分块传输编码实现动态流式输出。
而 Nginx 作为反向代理,默认配置是为 "短连接、完整响应"(如静态资源、普通 API)优化的,其默认行为与 SSE 需求直接冲突:
- 缓冲机制:Nginx 会缓存后端响应数据,直到填满缓冲区(默认 4k/8k)才转发给客户端,导致小批量流式数据被 "攒着";
 - HTTP 版本兼容:默认可能使用 HTTP 1.0 与后端通信,不支持长连接和分块传输;
 - 缓存机制:Nginx 会缓存响应结果,导致 SSE 实时流被旧数据污染。
 
这些默认行为,最终导致 React 前端无法实时接收数据,出现 "分段卡顿"。
二、现象复现:React 中的卡顿表现
1. 核心代码示例
后端(如 Node.js)模拟逐字推送:
            
            
              javascript
              
              
            
          
          // 后端 SSE 接口
app.get('/sse/stream', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  const text = "实时流式输出测试";
  let index = 0;
  // 每 100ms 推送一个字符
  const interval = setInterval(() => {
    if (index < text.length) {
      res.write(`data: {"type":"normal","text":"${text[index]}"}\n\n`);
      index++;
    } else clearInterval(interval);
  }, 100);
});
        React 前端接收数据并更新:
            
            
              ini
              
              
            
          
          import { useState, useEffect } from 'react';
function SSEDemo() {
  const [streamingContent, setStreamingContent] = useState('');
  useEffect(() => {
    const es = new EventSource('/api/sse/stream');
    es.onmessage = (event) => {
      const res = JSON.parse(event.data);
      // 拼接流式数据
      if (res?.type === 'normal') {
        setStreamingContent(draft => draft + res?.text);
      }
    };
    return () => es.close();
  }, []);
  return <p>实时输出:{streamingContent}</p>;
}
        2. 卡顿现象
- 直接访问后端服务(
http://localhost:8080)时,前端逐字流畅显示; - 通过 Nginx 代理(
http://localhost)访问时,前端每隔 2-3 秒批量显示 20+ 字符,呈现 "蹦字" 式卡顿; - 网络请求中,SSE 响应数据 "批量到达",而非逐个字符实时传输。
 
三、解决方案:Nginx 三大关键配置
只需在 Nginx 的 SSE 接口代理配置中,添加以下三项核心配置,即可彻底解决卡顿:
            
            
              ini
              
              
            
          
          location /api/sse/stream {
  proxy_pass http://127.0.0.1:8080; # 后端 SSE 服务地址
  
  # 核心三配置
  proxy_http_version 1.1;
  proxy_cache off;
  proxy_buffering off;
  
  # 补充配置:延长超时、禁用压缩(保障长连接稳定)
  proxy_read_timeout 3600s;
  gzip off;
  proxy_set_header Connection "";
}
        配置作用深度解析
1. proxy_http_version 1.1;:筑牢 SSE 通信基础
- 强制 Nginx 与后端使用 HTTP 1.1 协议通信,而非默认的 HTTP 1.0;
 - HTTP 1.1 支持 
Connection: keep-alive长连接(SSE 持续推送的前提)和分块传输编码(服务器可随时发送小块数据); - 避免协议降级导致长连接断开或缓冲强制生效,为实时透传提供底层支持。
 
2. proxy_buffering off;:核心解决 "分段卡顿"
- 禁用 Nginx 的响应缓冲机制,后端输出的每一个字节都会立即转发给客户端;
 - 默认情况下,后端逐字推送的小数据会被 Nginx 缓存到缓冲区,攒够才转发,这是 "分段卡顿" 的直接原因;
 - 关闭缓冲后,数据实现 "实时透传",React 中的 
setStreamingContent能每 100ms 触发一次,呈现逐字输出效果。 
3. proxy_cache off;:保障 SSE 实时性
- 禁用 Nginx 代理缓存,避免 SSE 实时流被旧数据污染;
 - SSE 是动态实时数据(如实时日志、通知),每次连接输出都不同,缓存会导致后续客户端接收旧数据;
 - 确保每一次 SSE 连接都直接转发后端最新数据,避免实时性丢失。
 
四、验证与总结
1. 生效验证
- 视觉效果:React 页面逐字流畅显示,无批量卡顿;
 - 网络验证:F12 网络面板中,SSE 请求的响应体 "持续增长",而非一次性加载;
 - 响应头验证:包含 
Content-Type: text/event-stream、Transfer-Encoding: chunked,确认分块传输生效。 
2. 核心总结
React + SSE 流式卡顿的本质,是 Nginx 默认优化行为与 SSE 实时需求的冲突。三个关键配置各司其职:
proxy_http_version 1.1:解决 "协议支持" 问题,提供长连接和分块传输能力;proxy_buffering off:解决 "数据延迟" 问题,实现实时透传(核心);proxy_cache off:解决 "缓存污染" 问题,保障数据实时性。
只需简单配置这三项,再配合超时延长、禁用压缩等补充设置,就能让 Nginx 完美兼容 SSE 协议,为 React 项目提供流畅的实时流式体验。