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
相关产品推荐
相关产品推荐

