http.createServer 是在请求体接受完毕才执行 handle 吗?
发布于 8 个月前 作者 daGaiGuanYu 2993 次浏览 来自 问答

如下代码:

const http = require('http')

http.createServer((req, res) => {
  console.log('hello') // 输出 hello
  res.end('success')
}).listen(80)

如果请求体较大,我发现“输出 hello”那里,要等客户端上传完,才会执行。
那如果上传文件很大,内存是怎么受得了的?

有没有一种方法,在收到请求的时候,就可以拿到 IncomingMessage,
因为它是一个 ReadableStream,可以边读边往硬盘写。

5 回复

@index-js 我当然知道 req 就是 IncomingMessage……

你代码里的这个函数

(req, res) => {
  req.pipe(fs.create...)
}

是在服务器完全收到 body 之后才会执行
就是说,body 都收到了之后,才开始 pipe

文件上传这种功能都分离到cdn上传,才是正解

当然不是, 请求头接手完毕就可以响应了. http header 交换完毕即建立双向流, body 是一个可写流, 你说的这个情况"要等客户端上传完,才会执行"是因为你的客户端请求库选择将流一次性全部发送完毕而不是以流发送导致的

如果上传文件很大,内存是怎么受得了的?

  1. 服务端可以选择是否接受 http body, 不接受的话不占用任何内存.
  2. 就算接受超大文件也不会爆内存, 因为 node 是流式处理数据的, 只占用 chunk 的内存大小. (其实所有的后端都是流式处理数据的, 爆内存只是因为把数据都放到内存里了, 正确做法是转存到文件里)

@shynome 我是在浏览器里用 fetch api 上传的文件,刚刚看了这篇,好像确实是客户端的问题

我下午试一下,太感谢了~~

我就寻思着,如果 nodejs 等请求体接受完才开始处理,那也太不正经了,哈哈

请求 Header 被解析完了就执行。request body 如何处理,是交给业务自己处理的。

回到顶部