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

使用JS Stream API将Node.js流数据传到React前端无法实时输出如何解决

问题原因及修改方案

后端修改(server.js)

  1. 补全响应头配置,禁用所有环节的缓冲,新增Connection: keep-alive和反代缓冲禁用标识
  2. 启动Python进程时添加-u参数,强制关闭Python的标准输出缓冲,避免Python层缓存输出内容
  3. 禁用当前路由的压缩中间件(如果你的Node服务用了express的compression等压缩插件)
    修改后的代码:
// 先禁用当前路由的压缩逻辑
firmwareRouter.get('/run_test', (req, res, next) => {
  // 强制不使用压缩,避免压缩中间件缓存数据
  req.headers['accept-encoding'] = 'identity';
  next();
}, (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    // 禁用nginx等反向代理的缓冲
    'X-Accel-Buffering': 'no'
  });
  const pathToExample = '/server/path/to/test.py';
  const { spawn } = require('child_process');
  // 加-u参数开启Python无缓冲模式
  const pythonProcess = spawn('python', ['-u', pathToExample]);
  pythonProcess.stdout.on('data', (data) => {
    res.write(data);
  });
  pythonProcess.on('close', (code) => {
    res.end('Process has ended');
  });
});

前端修改(Firmware.js)

  1. 删除GET请求中无意义的Content-Type请求头,该字段仅用于标识请求体格式,GET请求无请求体不需要设置
  2. TextDecoder解码时添加stream: true配置,避免跨数据块的字符缓存
  3. 状态更新改为追加逻辑,避免每次覆盖之前的输出内容
    修改后的版本1参考代码:
import { useState, Fragment } from 'react';
export default function Firmware(props) {
  const [data, setData] = useState('');
  async function runTest() {
    try {
      const url = 'api/firmware/run_test'
      const request = {
        method: 'GET',
        headers: {}
      }
      const res = await fetch(url, request);
      const reader = res.body.getReader();
      const decoder = new TextDecoder('utf-8');
      let done, value;
      while (!done) {
        ({ value, done } = await reader.read());
        if (done) break;
        const chunk = decoder.decode(value, { stream: true });
        console.log(chunk);
        // 追加数据而不是覆盖
        setData(prev => prev + chunk);
      }
    } catch (err) {
      console.log('frontend:Firmware', err);
    }
  }

  return (
    <Fragment>
      <pre>{data}</pre>
      <button onClick={() => runTest()}>Run Test </button>
    </Fragment >
  )
}

开发环境代理配置修改

如果你在本地用了webpack-dev-server、vite等前端开发服务的反向代理,需要关闭代理的缓冲配置:

  • webpack代理配置新增:buffer: false, proxyTimeout: 0
  • vite代理配置新增:proxy: { '/api': { target: '你的后端地址', buffer: false, proxyTimeout: 0 } }

验证方法

你可以先直接用curl请求后端接口curl http://你的后端地址/api/firmware/run_test,如果curl能实时输出内容,说明后端逻辑正常,问题出在前端或者代理层;如果curl也不能实时输出,优先排查后端配置。

内容的提问来源于stack exchange,提问作者Glenn Oberlander

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:45:03