我正在尝试构建一个假设与快速服务器一起使用的http模块。
在读取http模块api时,我发现它没有将主体保存在请求对象中。 所以我的问题是:
http module
:监听套接字,如果我得到content-length
标头,则听取套接字流的其余部分直到我得到所有正文,保存它作为http请求的成员,然后才将请求对象发送到快速服务器处理程序。通过request.on('data',callback(data))让快递服务器“监听”请求主体,上面提出的建议有哪些优点和缺点
我的意思是,为什么我不应该像保留标题那样将主体保留在'request'对象中?
答案 0 :(得分:7)
如果不确切知道自己想做什么,很难回答你的问题。但是我可以给你一些关于Node / Express如何处理请求体的详细信息,希望你可以从那里拿东西。
处理请求时(直接通过Node的请求处理程序或通过Express的请求处理程序),将不会自动接收请求正文:您必须打开HTTP流才能接收请求。
正文内容的类型应由Content-Type
请求标头确定。两种最常见的身体类型是application/x-www-form-urlencoded
和multipart/form-data
。但是,可以使用您想要的任何内容类型,这通常对于API更常见(例如,使用application/json
变得越来越常见于REST API)。
application/x-www-form-urlencoded
非常简单; name=value
对是URL编码的(例如,使用JavaScript的内置encodeURIComponent
),然后与&符号(&)结合使用。它们通常是UTF-8编码的,但也可以在Content-Type
中指定。
multipart/form-data
更复杂,通常也可能非常大,因为vkurchatkin的答案指出(意味着你可能不想将它带入记忆中)。
Express提供了一些中间件来自动处理各种类型的正文解析。通常,人们只需使用bodyParser
,但您必须小心使用该中间件。它实际上只是一个结合了json
,urlencoded
和multipart
的便利中间件。但是,multipart
已被弃用。 Express仍在捆绑Connect 2.12,其中仍包含multipart
。但是,当Express更新其依赖关系时,情况将会改变。
在我写这篇文章时,bodyParser
,json
,urlencoded
和multipart
都已从Connect中删除。除multipart
之外的所有内容都已移至模块body-parser
(https://github.com/expressjs/body-parser)。如果你需要多部分支持,我推荐Busboy(https://npmjs.org/package/busboy),它非常强大。在某些时候,Express会更新它对Connect的依赖性,并且很可能会将依赖项添加到body-parser
,因为它已从Connect中删除。
因此,由于bodyParser
捆绑了已弃用的代码(multipart
),因此我建议仅在json
和urlencoded
明确关联(您甚至可以忽略json
如果您不接受任何JSON编码的实体):
app.use(express.json());
app.use(express.urlencoded());
如果您正在编写中间件,您可能不希望自动链接json
和urlencoded
(更不用说Busboy)了;这会破坏Express的模块化特性。但是,您应该在文档中指定您的中间件需要req.body
对象可用(如果不是,则优雅地失败):您可以继续说json
,{{1}并且Busboy都提供urlencoded
对象,具体取决于您需要接受的内容类型。
如果您深入研究req.body
或urlencoded
的源代码,您会发现它们依赖于另一个节点模块json
,它只是打开请求流并检索正文内容。如果您确实需要了解从请求中检索正文的详细信息,您将在该模块的源代码中找到所需的一切(https://github.com/stream-utils/raw-body/blob/master/index.js)。
我知道这很详细,但它们是重要的细节!
答案 1 :(得分:0)
你可以做到这一点,相当简单。 bodyParser
中间件就是这样做的,例如(https://github.com/expressjs/body-parser/blob/master/index.js#L27)。问题是,请求体可能非常大(例如文件上传),因此您通常不希望将其放入内存中。相反,您可以将其流式传输到磁盘或s3或其他。