人体解析器如何表达?


339

我不明白为什么需要body-parserExpress应用程序,因为无需使用即可获取数据body-parser。它实际上是做什么的?


54
为了读取HTTP POST数据,我们必须使用“ body-parser”节点模块。body-parser是一段快速的中间件,它读取表单的输入并将其存储为可通过以下方式访问的javascript对象req.body
重构

2
使用express可以读取HTTP请求中的任何数据,例如标头 req.headers(数组),可以读取http数据包的主体(如req.body@CleanCrispCode所述),并且可以读取为查询参数req.query.variable,这是有帮助的,因为express在javascript中自动转换了请求物件
Fernando Zamperin

3
@refactor -这可能是一个的原因是多方面的,我们必须用身体解析器,但它并没有说什么它做,即HTTP请求和响应对象是流,他们不是“读”为单个对象就像res.body没有res.body先将整个流缓冲到第一流一样。
Ortonomy

1
在Express版本4.16+中,它们包含了自己内置的body-parser版本,因此您不必提取此软件包。
StefanBob

Answers:


255

HTTP POSTExpress.js版本4及更高版本中处理请求,您需要安装名为的中间件模块body-parser

body-parser提取传入请求流的整个正文部分并将其公开req.body

中间件是Express.js的一部分,但现在您必须单独安装。

body-parser模块解析使用HTTP POST请求提交的JSON,缓冲区,字符串和URL编码的数据。body-parser如下所示使用NPM 安装。

npm install body-parser --save

在2019年4月2 日中进行编辑:在express@4.16.0中,与express捆绑在一起的body-parser中间件。有关更多详细信息,请参阅此


126
这很可能是有史以来最沉闷的事情。Express Express的核心开发人员为什么要通过为Web开发中最常见的用例安装额外的中间件,而使新手难以置信呢?
elmt

5
@elmt如果您想发表自己的见解,请尝试sails.js
George

1
@ user1063287是的。urlencoded()并且json()实际上是中间件工厂,它们返回调用的中间件功能next()
Nick Manning

3
它不是la脚的@elmt,节点不仅用于Web,它还可以在台式机,移动设备等上使用,在这些情况下,它不是必需的模块。Node可以适应您的应用程序而无需承担任何责任
fnaquira

28
@fnaquira-你很困惑。这是关于表达而不是节点。
Elmt

85

是的,我们可以没有body-parser。如果不使用它,则会得到原始请求,并且正文和标头不在request参数的根对象中。您将必须单独操作所有字段。

或者您可以使用body-parser,因为快递团队正在维护它。

身体解析器可以为您做什么:简化了请求。
使用方法:以下是示例:

安装 npm install body-parser --save

这在快递中如何使用body-parser:

const express = require('express'),
      app = express(),
      bodyParser = require('body-parser');

// support parsing of application/json type post data
app.use(bodyParser.json());

//support parsing of application/x-www-form-urlencoded post data
app.use(bodyParser.urlencoded({ extended: true }));

链接。

https://github.com/expressjs/body-parser

然后,您可以在根请求对象中获取正文和标头。例

app.post("/posturl",function(req,res,next){
    console.log(req.body);
    res.send("response");
})

3
嘿,谢谢您提供的信息,您可以发布没有正文解析器的代码示例吗?
Ilyas karim

55

这里的答案非常详细而精彩地解释了它,其中包含:

简而言之; body-parser提取传入请求流的整个主体部分,并将其公开req.body为易于接口的内容。您本身并不需要它,因为您可以自己完成所有这些操作。但是,它很可能会做您想做的事并为您省去麻烦。


深入一点 body-parser提供了一个中间件,该中间件使用nodejs / zlib解压缩传入的请求数据(如果已压缩),并使用stream-utils / raw- body在“解析”之前等待请求主体的完整原始内容(这意味着您不会使用请求正文,只是浪费了一些时间)。

拥有原始内容之后,body-parser会使用四种策略之一来解析它,具体取决于您决定使用的特定中间件:

  • bodyParser.raw() :实际上不解析身体,而只是从之前的公开缓冲了内容缓存req.body

  • bodyParser.text():以纯文本形式读取缓冲区,并在req.body中公开结果字符串。

  • bodyParser.urlencoded():将文本解析为URL编码的数据(这是浏览器倾向于从设置为POST的常规表单发送表单数据的方式),并在上公开结果对象(包含键和值)req.body。为了比较;在PHP中,所有这些都是自动完成的,并在中公开$_POST

  • bodyParser.json():将文本解析为JSON并在上公开结果对象req.body

只有将设置req.body为所需的内容后,它才会调用堆栈中的下一个中间件,然后该中间件可以访问请求数据,而不必考虑如何解压缩和解析它。

您可以参考body-parser github来阅读其文档,其中包含有关其工作的信息。


47

让我们尝试保持最低限度的技术性。

假设您正在将HTML表单数据发送到node-js服务器,即您向服务器发出了请求。服务器文件将在请求对象下接收您的请求。现在按逻辑,如果您在服务器文件中控制台记录此请求对象,则应该在其中的某些位置看到表单数据,然后可以将其提取出来,但是哇!你实际上不!

那么,我们的数据在哪里?如果它不仅出现在我的请求中,我们将如何提取它。

对此的简单解释是,http将您的表单数据逐位发送,以便在到达目的地时进行组装。那么您将如何提取数据。

但是,为什么要每次手动手动分析数据块并将其组装起来却费心。使用一种叫做“ body-parser”的东西,它可以为您做这件事。

body-parser解析您的请求并将其转换为一种格式,您可以从中轻松提取您可能需要的相关信息。

例如,假设您在前端有一个注册表单。您正在填充它,并请求服务器将详细信息保存在某处。

如果使用body-parser,从请求中提取用户名和密码将变得非常简单。

var loginDetails = {    
    username : request.body.username,    
    password : request.body.password    
};

因此,基本上,body-parser解析您的传入请求,组装包含表单数据的块,然后为您创建此body对象并用表单数据填充它。


10

它解析HTTP请求正文。当您需要了解的不仅仅是击中的URL时,通常这是必需的,特别是在POST或PUT PATCH HTTP请求的上下文中,其中您想要的信息包含在正文中。

基本上,它是一种用于解析JSON,纯文本或仅返回原始Buffer对象供您根据需要处理的中间件。



7

这些都是为了方便。

基本上,如果问题是“我们需要使用body-parser吗?” 答案是不'。我们可以使用更circuit回的路由从请求后的客户机中获得相同的信息,该路由通常较不灵活,并且将增加为获得相同信息而必须编写的代码量。

这与询问“我们需要使用express开始吗?” 有点类似。再次,答案是没有的,而且确实如此,这全都归功于我们免去编写更多代码来执行“内置”所表达的基本操作的麻烦。

从表面上看- body-parser可以更轻松地获取各种格式的客户请求中包含的信息,而不是使您捕获原始数据流并弄清楚信息的格式,而无需手动将信息解析为可用数据。


6

了解请求正文

当接收到POST或PUT请求时,请求主体对于您的应用程序可能很重要。获取主体数据比访问请求标头要复杂得多。传递给处理程序的请求对象实现ReadableStream接口。就像其他任何流一样,可以在其他地方收听或通过管道传输此流。通过侦听流的“数据”和“结束”事件,我们可以从流中直接获取数据。

每个“数据”事件中发出的块是一个缓冲区。如果您知道它将是字符串数据,那么最好的办法是将数据收集到一个数组中,然后在“末尾”将其连接并字符串化。

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // at this point, `body` has the entire request body stored in it as a string
});

了解身体分析器

根据其文档

在处理程序之前,在中间件中解析传入的请求主体,该处理程序在req.body属性下可用。

正如您在第一个示例中看到的那样,我们必须手动解析传入的请求流以提取主体。当存在不同类型的多种表单数据时,这变得有些繁琐。因此,我们使用body-parser包在后台执行所有此任务。

它提供了四个模块来解析不同类型的数据

拥有原始内容后,body-parser将使用上述策略之一(取决于您决定使用的中间件)来解析数据。您可以通过阅读他们的文档来了解更多有关他们的信息。

将设置req.body为已解析的正文之后,body-parser将调用next()以调用堆栈中的下一个中间件,然后该中间件可以访问请求数据,而不必考虑如何解压缩和解析它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.