使用Node.js和Express进行发布时如何访问请求正文?


175

我有以下Node.js代码:

var express = require('express');
var app = express.createServer(express.logger());
app.use(express.bodyParser());

app.post('/', function(request, response) {
    response.write(request.body.user);
    response.end();
});

现在,如果我发布类似的内容:

curl -d user=Someone -H Accept:application/json --url http://localhost:5000

我得到Someone了预期的结果。现在,如果我想获得完整的请求正文怎么办?我尝试这样做,response.write(request.body)但是Node.js抛出一个异常,说“ 第一个参数必须是字符串或缓冲区 ”,然后转到“无限循环”,并出现异常,指出“ 发送标头后不能设置标头 ”。即使我var reqBody = request.body;再写了也是这样response.write(reqBody)

这是什么问题?

另外,我可以不使用而直接获得原始请求express.bodyParser()吗?


似乎有些东西response.write(reqBody); 当我使用时response.send(reqBody)一切正常...是的,我使用response.endafter response.write
TheBlueSky

Answers:


161

Express 4.0及更高版本:

$ npm install --save body-parser

然后在您的节点应用程序中:

const bodyParser = require('body-parser');
app.use(bodyParser);

Express 3.0及以下版本:

尝试在您的cURL调用中传递此代码:

--header "Content-Type: application/json"

并确保您的数据采用JSON格式:

{"user":"someone"}

另外,您可以在node.js代码中使用console.dir来查看对象中的数据,如以下示例所示:

var express = require('express');
var app = express.createServer();

app.use(express.bodyParser());

app.post('/', function(req, res){
    console.dir(req.body);
    res.send("test");
}); 

app.listen(3000);

这个其他问题可能也有帮助:如何在快速的node.js POST请求中接收JSON?

如果您不想使用bodyParser,请查看以下其他问题:https ://stackoverflow.com/a/9920700/446681


我尝试使用,curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000但这给了我错误“ Unexpected token u ”,这就是为什么我切换到原始帖子中提到的呼叫的原因。
TheBlueSky


40
express.bodyParser()在Express 4.x中已弃用。请改用npmjs.org/package/body-parser
卢克,

@TheBlueSky之所以得到“意外令牌u”,是因为shell消耗了双引号。如果您做同样的事情echo any"thing"。您发布的数据应在引号内,以防止发生这种情况。
汤姆·费内奇

11
从express 4.16.0或更高版本开始,可以通过这种方式在app.use()中使用express.json()=> app.use(express.json());
Mitro

187

express v4.16开始,无需使用任何其他模块,只需使用内置的JSON中间件即可

app.use(express.json())

像这样:

const express = require('express')

app.use(express.json())    // <==== parse request body as JSON

app.listen(8080)

app.post('/test', (req, res) => {
  res.json({requestBody: req.body})  // <==== req.body will be a parsed JSON object
})

注意- body-parser这取决于它,已经包含在express中。

也不要忘记发送标题 Content-Type: application/json


14
谢谢,这是4.16+的最佳答案。没有其他依赖项,并且像魅力一样起作用!
codepleb

1
我能找到的最好的/唯一的解决办法并不需要身体解析器
莫特Zart

41

从Express 4开始,以下代码似乎可以解决问题。请注意,您需要body-parser使用安装npm

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));


app.listen(8888);

app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});

29
要解析json主体,需要添加以下行app.use(bodyParser.json())
Camilo Silva

1
@ cml.co是没有任何理由app.use(bodyParser.urlencoded({ extended: true })需要?我在请求中发布了一个相当复杂的文档,如JSON,extended: false但没有用。仅当我将其设置为true时,该请求才被正确解析。
网络用户

3
请注意。必须使用app.use(bodyParser.urlencoded({ extended: true }));AND app.use(bodyParser.json())在带有NodeJS和Express的AWS Linux服务器设置上获取json数据。
大卫

24
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())

var port = 9000;

app.post('/post/data', function(req, res) {
    console.log('receiving data...');
    console.log('body is ',req.body);
    res.send(req.body);
});

// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);

这将为您提供帮助。我假设您正在使用json发送正文。


我总是忘记添加bodyParser.json()位x_x谢谢!
乔尼·阿斯玛

14

对于2019,您不需要安装body-parser

您可以使用:

var express = require('express');
var app = express();
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.listen(8888);
app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});

8

此,可以实现无body-parser依赖关系,以及,听取request:datarequest:end,并返回对请求端的响应时,参考下面的代码示例。参考:https : //nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#request-body

var express = require('express');
var app = express.createServer(express.logger());

app.post('/', function(request, response) {

    // push the data to body
    var body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      // on end of data, perform necessary action
      body = Buffer.concat(body).toString();
      response.write(request.body.user);
      response.end();
    });
});

3

试试这个:

response.write(JSON.stringify(request.body));

这将采用bodyParser为您创建的对象,然后将其转换为字符串并将其写入响应。如果您想要确切的请求正文(具有相同的空格等),则需要在请求之前附加dataend侦听器,并逐块构建字符串,如在connect中从json解析源代码中看到的那样。


1

您声称已“尝试执行”的操作正是您在使用curl调用时按“预期”工作的代码中编写的内容。

您收到的错误似乎与您显示给我们的任何代码都不相关。

如果要获取原始请求,请requestdataend事件设置处理程序为开(当然,还应删除的所有调用express.bodyParser())。请注意,data事件将以块的形式发生,并且除非您为data事件设置编码,否则这些块将是缓冲区而不是字符串。


那是一个复制粘贴错误;我的意思request.body不是request.body.user,现在纠正了。顺便说一句,var reqBody = request.body;过去还是现在仍然正确,当您尝试它时,您会得到我得到的错误。无论如何,能否请您举例说明如何将处理程序设置为request; 我似乎没有在快速指南中找到它。
TheBlueSky

1

如果您足够懒惰,可以读取大块的发布数据。您可以简单地将以下行粘贴以读取json。

以下是针对TypeScript的代码,也可以对JS进行类似操作。

应用程序

 import bodyParser from "body-parser";
 // support application/json type post data
 this.app.use(bodyParser.json());
 // support application/x-www-form-urlencoded post data
 this.app.use(bodyParser.urlencoded({ extended: false }));

在接收POST呼叫的任何控制器之一中,如下所示

userController.ts

 public async POSTUser(_req: Request, _res: Response) {
   try {
          const onRecord = <UserModel>_req.body;
           /* Your business logic */
           _res.status(201).send("User Created");
        }
    else{
           _res.status(500).send("Server error");
           }        
   };

_req.body应该将json数据解析为TS模型。


1
我不确定您是否通过鼓励他们变懒来鼓励或劝阻人们使用您的答案:)
TheBlueSky

1

我绝对不是JS和ES的新手,但似乎对我有用的就是:

JSON.stringify(req.body)

让我知道它有什么问题!


正是我需要的
Josef Henn

0

通过以下命令安装Body Parser

$ npm install --save body-parser

配置正文解析器

const bodyParser = require('body-parser');
app.use(bodyParser);
app.use(bodyParser.json()); //Make sure u have added this line
app.use(bodyParser.urlencoded({ extended: false }));

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.