如何用Node.js Express在POST请求中向客户端实时流式传输数据
实时传输动态生成数据到客户端的解决方案
你的核心问题是普通HTTP响应是一次性的,res.send()发送后连接就关闭了,没法持续推送后续更新的数据。要实现实时单向推送,最简便的方案是用服务器发送事件(SSE),以下是具体实现:
修改后的完整代码
const express = require('express'); const { createWriteStream } = require('fs'); const app = express(); const port = 3000; app.post('/', (req, res) => { // 配置SSE响应头,保持连接并禁用缓存 res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); res.flushHeaders(); // 立即发送响应头 // 初始化CSV写入流(保持打开状态,避免重复创建) const csvStream = createWriteStream('./results.csv', { flags: 'a', encoding: 'utf8' }); // 定时生成并推送数据的任务 const intervalId = setInterval(() => { // 模拟生成Name和Age数据(替换成你实际的生成逻辑) const Name = `User_${Math.floor(Math.random() * 9000) + 1000}`; const Age = Math.floor(Math.random() * 50) + 18; // 写入CSV csvStream.write(`${Name}, ${Age}\n`); // 以SSE格式推送给客户端 res.write(`data: ${JSON.stringify({ name: Name, age: Age })}\n\n`); }, 10000); // 每10秒执行一次 // 监听客户端断开连接事件,清除定时任务并关闭CSV流 req.on('close', () => { clearInterval(intervalId); csvStream.end(); res.end(); }); }); app.listen(port, () => { console.log("App is running on port " + port); });
关键说明
- SSE响应头配置:必须设置
text/event-stream类型,同时禁用缓存、保持长连接,确保数据能实时推送到客户端。 - 持续推送用
res.write():不能用res.send(),因为它会直接结束响应连接;res.write()可以多次发送数据而不关闭连接。 - SSE消息格式:每条消息必须以
data: 内容\n\n的格式发送,这里用JSON序列化数据是为了客户端更易解析。 - 资源清理:客户端断开时一定要清除定时任务、关闭CSV流,避免内存泄漏和资源浪费。
客户端接收示例(前端代码)
如果需要前端配合接收数据,可以用以下代码:
// 发起POST请求后建立SSE连接(注意实际项目中要处理跨域等问题) const eventSource = new EventSource('/sse'); // 建议单独开SSE路由,逻辑更清晰 eventSource.onmessage = function(event) { const data = JSON.parse(event.data); console.log('收到实时数据:', data); // 这里可以把数据渲染到页面上 }; eventSource.onerror = function(error) { console.error('SSE连接出错:', error); eventSource.close(); };
注:如果需要双向通信(比如客户端给服务端发指令),可以考虑用WebSocket,但SSE在单向推送场景下实现更简单、开销更小。
内容的提问来源于stack exchange,提问作者Patrick Preston
相关产品推荐
相关产品推荐

