已建立HTTP连接但Node.js服务器data事件回调未触发
问题:HTTP服务器未接收流式JSON数据(req.on('data')无触发)
服务器能触发console.log('request received.'),但req.on('data')回调从未执行,客户端尝试逐行流式传输JSON数据。
服务器端代码
const http = require('http'); const s = http.createServer((req, res) => { console.log('request received.'); // 能正常打印 req.on('data', d => { console.log('hello data:', String(d)); // 从未触发 }); }); s.listen(4444);
客户端代码
const http = require('http'); const r = http.request({ protocol: 'http:', port: 4444, timeout: 500 }, res => { res.on('data', d => { console.log('response from server:', res); }); }); let requestNum = 1; (async () => { while (1) { console.log('writing:', {requestNum}); const json = JSON.stringify({ timeSent: Date.now(), requestNum: requestNum++ }); r.write(json + '\n'); await new Promise(resolve => setTimeout(resolve, 500)); } })();
问题原因及修复方案
1. 默认GET请求不支持请求体
HTTP规范中,GET请求通常不携带请求体,Node.js的http服务器默认会忽略GET请求的请求体数据,因此不会触发data事件。
修复:
客户端请求配置添加method: 'POST'(或PUT等允许携带请求体的方法):
const r = http.request({ protocol: 'http:', port: 4444, method: 'POST', // 新增指定请求方法 timeout: 500 }, res => { // ... 原有代码 });
2. 客户端超时设置过短导致连接中断
客户端设置的timeout:500会让socket在500毫秒无活动时自动断开,而你的循环刚好每500毫秒发送一次数据,容易触发超时,导致连接提前关闭,数据无法正常传输。
修复:
移除或增大超时时间,根据实际需求调整:
const r = http.request({ protocol: 'http:', port: 4444, method: 'POST', // timeout: 500 // 移除该配置,或改为更大的值(如5000) }, res => { // ... 原有代码 });
3. 服务器未响应请求引发连接异常
服务器收到请求后未发送任何响应,长时间保持的连接可能触发系统层面的超时机制,影响数据传输稳定性。
修复:
监听请求的end事件并发送响应:
const s = http.createServer((req, res) => { console.log('request received.'); req.on('data', d => { console.log('hello data:', String(d)); }); // 请求结束后发送响应 req.on('end', () => { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Data received'); }); });
内容的提问来源于stack exchange,提问作者Alexander Mills
相关产品推荐
相关产品推荐

