http请求对象上的node.js主体与快速请求对象上的主体

时间:2014-01-07 18:08:16

标签: node.js sockets http express

我正在尝试构建一个假设与快速服务器一起使用的http模块。

在读取http模块api时,我发现它没有将主体保存在请求对象中。 所以我的问题是:

  1. 如果我想构建一个与官方http模块配合使用的快速服务器,我应该如何获取正文?
  2. 我考虑以下列方式实现http module:监听套接字,如果我得到content-length标头,则听取套接字流的其余部分直到我得到所有正文,保存它作为http请求的成员,然后才将请求对象发送到快速服务器处理程序。
  3. 通过request.on('data',callback(data))让快递服务器“监听”请求主体,上面提出的建议有哪些优点和缺点

    我的意思是,为什么我不应该像保留标题那样将主体保留在'request'对象中?

2 个答案:

答案 0 :(得分:7)

如果不确切知道自己想做什么,很难回答你的问题。但是我可以给你一些关于Node / Express如何处理请求体的详细信息,希望你可以从那里拿东西。

处理请求时(直接通过Node的请求处理程序或通过Express的请求处理程序),将不会自动接收请求正文:您必须打开HTTP流才能接收请求。

正文内容的类型应由Content-Type请求标头确定。两种最常见的身体类型是application/x-www-form-urlencodedmultipart/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,但您必须小心使用该中间件。它实际上只是一个结合了jsonurlencodedmultipart的便利中间件。但是,multipart已被弃用。 Express仍在捆绑Connect 2.12,其中仍包含multipart。但是,当Express更新其依赖关系时,情况将会改变。

在我写这篇文章时,bodyParserjsonurlencodedmultipart都已从Connect中删除。除multipart之外的所有内容都已移至模块body-parserhttps://github.com/expressjs/body-parser)。如果你需要多部分支持,我推荐Busboy(https://npmjs.org/package/busboy),它非常强大。在某些时候,Express会更新它对Connect的依赖性,并且很可能会将依赖项添加到body-parser,因为它已从Connect中删除。

因此,由于bodyParser捆绑了已弃用的代码(multipart),因此我建议仅在jsonurlencoded明确关联(您甚至可以忽略json如果您不接受任何JSON编码的实体):

app.use(express.json());
app.use(express.urlencoded());

如果您正在编写中间件,您可能不希望自动链接jsonurlencoded(更不用说Busboy)了;这会破坏Express的模块化特性。但是,您应该在文档中指定您的中间件需要req.body对象可用(如果不是,则优雅地失败):您可以继续说json,{{1}并且Busboy都提供urlencoded对象,具体取决于您需要接受的内容类型。

如果您深入研究req.bodyurlencoded的源代码,您会发现它们依赖于另一个节点模块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或其他。