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

Node.js无法发送分块文本响应?Express与XHR实现求助

问题原因及解决方案

你遇到的问题核心在于服务器端没有明确启用分块传输编码,且Node.js的响应缓冲区会延迟发送小数据块,导致两次res.write的内容被合并后一次性发送给客户端。

具体解决步骤

1. 开启分块传输编码

在服务器代码中,先设置响应头明确告知客户端使用分块传输,注意不要设置Content-Length头(分块传输不需要该字段):

server.post('/ask', async function(req, res, next) {  
  // 开启分块传输编码
  res.setHeader('Transfer-Encoding', 'chunked');
  // 指定内容类型,避免浏览器解析异常
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  
  res.write("hello");
  setTimeout(function(){
    res.write("world");
    res.end();
  }, 5000)
});

2. 强制刷新响应缓冲区

Node.js的响应流默认会缓冲小数据(默认阈值约16KB),直到缓冲区满才会发送。因此每次res.write后需要调用res.flush()强制发送当前数据块:

server.post('/ask', async function(req, res, next) {  
  res.setHeader('Transfer-Encoding', 'chunked');
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  
  res.write("hello");
  res.flush(); // 立即发送第一个分块
  
  setTimeout(function(){
    res.write("world");
    res.flush(); // 可选,res.end 会自动发送剩余数据
    res.end();
  }, 5000)
});

3. 禁用压缩中间件(如果启用了)

如果你的Express项目使用了compression中间件开启Gzip/Brotli压缩,压缩机制会合并所有分块后再发送,导致onprogress无法触发。可以给该路由单独禁用压缩:

const compression = require('compression');

// 对/ask路由禁用压缩
server.post('/ask', compression({ filter: () => false }), async function(req, res, next) {
  // ... 上述服务器代码
});

完成上述修改后,客户端的onprogress事件会按预期触发两次:第一次返回hello,第二次返回helloworld。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 01:12:16