Node.js HTTP服务器异步接收请求体的底层存储机制疑问
关于Node.js HTTP服务器请求体存储位置的疑问
我近期用Node.js编写HTTP服务器代码,但难以理解其底层运行机制,尤其是Node.js接收请求体的方式。我原本认为客户端会在单次HTTP请求中同时发送请求行、请求头和请求体,因此请求体应与前两者一同被接收。但实际在Node.js中却可以异步接收请求体,甚至延迟10秒也能获取到。
我用Bun编写的客户端代码如下:
// client.js with bun const response = await fetch('http://127.0.0.1:3000', { method: 'POST', headers: { 'content-type': 'text/plain; charset=UTF-8', }, body: 'Hello, Server! This is Client.' });
通过Wireshark抓包证实,请求行、请求头和请求体是单次发送的,对应的Node.js服务器代码如下:
// server.mjs with node.js import { createServer } from 'node:http'; async function delay(timeout) { return new Promise(resolve => { setTimeout(resolve, timeout); }); } createServer(async (req, res) => { console.log(req.url); console.log(req.method); console.log(req.headers['content-type']); setTimeout(async () => { const chunkArr = []; req.on('data', chunk => { chunkArr.push(chunk); }); req.on('end', () => { console.log(Buffer.concat(chunkArr).toString()); }); }, 1000); for (let i = 0; i < 10; i++) { await delay(1000); console.log(i + 1); } }).listen(3000);
请问延迟的10秒内请求体存储在哪里?是存在Node.js的缓存中吗?
答案
延迟的10秒内,请求体其实存储在操作系统的TCP接收缓冲区中,而非Node.js自身的缓存。
具体原因如下:
- TCP是流式传输协议,当客户端一次性发送完整的HTTP请求(包含请求体)后,操作系统会先将接收到的数据暂存到TCP接收缓冲区里。
- Node.js中的
req对象本质是基于TCP套接字的可读流,在你没有监听data事件之前,Node.js不会主动从TCP缓冲区读取数据。这部分数据会一直留在操作系统的缓冲区中,直到你开始监听data事件,Node.js才会从缓冲区读取数据并触发data回调函数。 - 你代码里的10秒延迟只是让Node.js的事件循环暂停处理请求体的读取逻辑,但操作系统已经完整接收了所有请求数据,所以当后续绑定
data和end事件时,Node.js能立刻从缓冲区中读取到全部请求体内容。
简言之:Node.js未准备好处理请求体时,数据会暂存在操作系统的TCP缓存中,等你触发读取逻辑时再获取。
内容的提问来源于stack exchange,提问作者Devin Johw
相关产品推荐
相关产品推荐

