Express.js req.body未定义


291

我将其作为Express服务器的配置

app.use(app.router); 
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

但是当我req.body.something在路线上询问时,仍然会指出一些错误body is undefined。这是使用的路线的示例req.body

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

我读到这个问题是由于缺少引起的,app.use(express.bodyParser());但是如您所见,我在路由之前将其称为。

有什么线索吗?

Answers:


296

您必须确保在定义路由之前定义所有配置。如果这样做,您可以继续使用express.bodyParser()

示例如下:

var express = require('express'),
    app     = express(),
    port    = parseInt(process.env.PORT, 10) || 8080;

app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});

app.listen(port);

app.post("/someRoute", function(req, res) {
  console.log(req.body);
  res.send({ status: 'SUCCESS' });
});

9
这对我有用。注意:不幸的是,那里的一些教程(例如我)有些人将路线放在app.configure()之前。在我的情况下,形式为app.get / post等,包括它们的require()。
bentman

1
非常感谢,我整天都在解决这个问题。
jfplataroti

11
从Express 4开始,删除了app.use(app.router)。请参阅文档github.com/visionmedia/express/wiki/New-features-in-4.x
Jonathan Ong,

14
从express 4开始,像bodyParser这样的中间件不再与Express捆绑在一起,必须单独安装。您可以在这里找到更多信息:github.com/senchalabs/connect#middleware
andrea.rinaldi 2014年

2
谢谢。这个答案已有2年多的历史了,并且仍然在帮助遇到麻烦的人:)
Lorenzo Marcon 2015年

275

Express(4.x)的最新版本已将中间件与核心框架分离。如果需要正文解析器,则需要单独安装

npm install body-parser --save

然后在您的代码中执行此操作

var bodyParser = require('body-parser')
var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

2
我最近更新为表达4.x。最初,当我尝试登录req.body时,它向我显示未定义。一旦我安装并使用了body解析器,它就会为我提供预期的req.body值。:)
Alok Adhao 2015年

当试图弄清楚为什么我的POST请求不能与json-server一起工作时,我发现这很有用。
freethebees

保存了我的一天,尤其是部分'app.use(bodyParser.json())'。多谢兄弟 !:D
neaGaze

这应该是公认的答案,因为它完全适用于Express 4!谢谢你,先生!
合并

2
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) 救了我 !!
Pramesh Bajracharya

70

否。您需要使用app.use(express.bodyParser())之前app.use(app.router)。实际上,app.use(app.router)应该是您最后要打的电话。


连动app.use(app.router).use的呼叫不能解决问题:(。
Masiar

好吧,经过一番苦苦挣扎之后,我使用app.use(require('connect').bodyParser());代替来解决了它app.use(express.bodyParser());
Masiar

是的,即使使用,答案也是正确的var router=express.Router()
Istiaque Ahmed

1
轻微的附录,您仍然应该在app.router之后调用错误处理中间件
Craft

BLESS此评论

40

首先,请确保通过调用以下命令安装了名为“ body-parser”的npm模块:

npm install body-parser --save

然后,在呼叫路线之前,请确保已包含以下几行

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

app.use(bodyParser.json());

如果使用express.json,那么为什么要导入body-parser?
SanSolo

38

Express 4,具有内置的正文解析器。无需安装单独的正文解析器。所以下面的工作:

export const app = express();
app.use(express.json());

37

请求标头中的Content-Type非常重要,尤其是当您从curl或任何其他工具发布数据时。

确保您使用诸如application / x-www-form-urlencoded,application / json之类的东西,这取决于您的帖子数据。将此字段保留为空会混淆Express。


12
+1这是我的问题。我使用Chrome的Postman来测试REST内置的JSON api,但Express每次收到的对象都是空的。事实证明,即使您选择raw> json ,Postman默认也不自动添加'Content-Type:application / json'标头。
约旦

@Jordan +1感谢您指出这一点。实际上,我只是检查了标头,即使选择了“ json”,我仍将其设置为“ text / plain”。
工程师

gh ... 7年后的今天,这仍然是让我
震惊的原因

33

正如已经在一个评论下发布的那样,我使用

app.use(require('connect').bodyParser());

代替

app.use(express.bodyParser());

我仍然不知道为什么简单的express.bodyParser()方法不起作用...


1
@Masiar这对我不起作用。我正在使用expressjs 4&我得到这样的错误。错误:找不到模块“连接”
Jeyarathnem Jeyachanthuru

1
@JeyTheva的地雷是一个非常老的解决方案,因此在此期间情况可能已发生变化。我建议您尝试通过安装connect模块,npm install connect然后重试。通过读取错误的输出,这是我唯一能想到的。
2014年

4
这是解决此问题的最新文档:npmjs.com/package/body-parser 对于遇到此问题的其他人“ post express 4”,对我有用的是将Content-Type标头设置为application/json
Grant Eagon

3
这是解决此问题的最新文档:npmjs.com/package/body-parser 安装了body-parser后,它仍然无法正常工作。所做的工作是在我执行请求时将Content-Type标头设置为application/json
Grant Eagon

1
application/jsonvs text/json在请求中有效,如@GrantEagon所建议。

21
// Require body-parser (to receive post data from clients)

var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json

app.use(bodyParser.json())

20

加入您的 app.js

在路由器呼叫之前

const app = express();
app.use(express.json());

2
你救了我这个男人!关键是在呼叫路由器之前添加线路
ubaldisney

这东西救了我。谢谢:)
Farrukh Faizy

12

似乎解析器不再与Express一起提供。我们可能必须单独安装。

var express    = require('express')
var bodyParser = require('body-parser')
var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!

有关更多信息和示例,请参考git页面https://github.com/expressjs/body-parser


1
这似乎是新的Express 4.x格式,对我有用。其他答案中提到的express.bodyParser()在4.x中不起作用。
DustinB

10

万一有人遇到我遇到的同一问题,我正在使用url前缀

http://example.com/api/

用路由器设置的

app.use('/api', router); 

然后我有以下

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

解决我问题的是将bodyparser配置放在上面 app.use('/api', router);

最后

// setup bodyparser
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

//this is a fix for the prefix of example.com/api/ so we dont need to code the prefix in every route
    app.use('/api', router); 

9

需要告知express.bodyParser()解析的内容是什么类型。因此,您需要确保在执行POST请求时,要包括“ Content-Type”标头。否则,bodyParser可能不知道如何处理POST请求的正文。

如果您使用curl来执行POST请求,该请求在主体中包含一些JSON对象,则它将看起来像这样:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute

如果使用其他方法,请确保使用适当的约定设置该标头字段。


8

使用app.use(bodyparser.json()); 在路由之前。//。app.use(“ / api”,路线);



7

由于缺少JSON解析器,大多数情况下req.body都是不确定的

const express = require('express');
app.use(express.json());

可能缺少人体分析器

const bodyParser  = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

有时由于cro的来源而未定义,请添加它们

const cors = require('cors');
app.use(cors())

5

今天发生在我身上。以上解决方案都不适合我。但是,稍作谷歌搜索就可以帮助我解决此问题。我正在为微信第三方服务器编码。

当您的node.js应用程序需要读取流式POST数据(例如来自REST客户端的请求)时,事情会变得稍微复杂一些。在这种情况下,请求的属性“可读”将设置为true,并且必须分块读取POST数据才能收集所有内容。

http://www.primaryobjects.com/CMS/Article144


该帖子提到HTML表单提交与REST Client请求不同。都不都是http请求吗?因此,POST是唯一需要流传输的情况?
j10

5

浪费了很多时间:

根据客户端请求中
的Content-Type,服务器应具有以下app.use()之一:

app.use(bodyParser.text({ type: 'text/html' }))
app.use(bodyParser.text({ type: 'text/xml' }))
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
app.use(bodyParser.json({ type: 'application/*+json' }))

来源:https : //www.npmjs.com/package/body-parser#bodyparsertextoptions

例:

对我来说,在客户端,我有以下标题:

Content-Type: "text/xml"

因此,在服务器端,我使用了:

app.use(bodyParser.text({type: 'text/xml'}));

然后,req.body工作正常。



4

要工作,您需要在app.use(express.bodyParser())之后添加app.use(app.router ,如下所示:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);

1
您的注释和代码段是矛盾的。首先,您说您必须先使用app.useon app.routerexpress.bodyParser但是您的代码清楚地表明它是AFTER之后的。那是什么呢?
维·罗伯茨

1
对不起。您需要在express.bodyParser之后使用app.router。
HenioJR 2014年

1
谢谢@LeviRoberts
HenioJR 2014年

4
var bodyParser = require('body-parser');
app.use(bodyParser.json());

这挽救了我的一天。


4

可能是因为您没有使用body-parser(link

var express = require('express');
var bodyParser  = require('body-parser');

var app = express();
app.use(bodyParser.json());

3

我解决了:

app.post('/', bodyParser.json(), (req, res) => {//we have req.body JSON
});


2

您可以使用快速正文解析器。

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

2

最新版本的Express已经内置了正文解析器。因此,您可以使用:

const express = require('express);
... 
app.use(express.urlencoded({ extended: false }))
.use(express.json());

1

如果您发布SOAP消息,则需要使用原始正文解析器:

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

app.use(bodyParser.raw({ type: 'text/xml' }));

1

建立在@ kevin-xue上的内容类型需要声明。在我的实例中,这仅在IE9中发生,因为XDomainRequest没有设置内容类型,因此bodyparser和expressjs忽略了请求的主体。

我通过在将请求传递到正文解析器之前显式设置content-type来解决此问题,如下所示:

app.use(function(req, res, next) {
    // IE9 doesn't set headers for cross-domain ajax requests
    if(typeof(req.headers['content-type']) === 'undefined'){
        req.headers['content-type'] = "application/json; charset=UTF-8";
    }
    next();
})
.use(bodyParser.json());

1

感谢@spikeyang为伟大的答案(下面提供)。阅读该帖子所附的建议文章后,我决定分享我的解决方案。

什么时候使用?

解决方案要求您使用Express路由器才能享受它。.因此:如果您尝试使用接受的答案没有任何运气,只需使用以下功能即可复制并粘贴:

function bodyParse(req, ready, fail) 
{
    var length = req.header('Content-Length');

    if (!req.readable) return fail('failed to read request');

    if (!length) return fail('request must include a valid `Content-Length` header');

    if (length > 1000) return fail('this request is too big'); // you can replace 1000 with any other value as desired

    var body = ''; // for large payloads - please use an array buffer (see note below)

    req.on('data', function (data) 
    {
        body += data; 
    });

    req.on('end', function () 
    {
        ready(body);
    });
}

并这样称呼:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

注意: 对于较大的有效负载-请使用数组缓冲区(更多@ MDN


通常使用bodyParser包,并将有效负载转换为主体对象。其他答案中提供的信息
Schuere

1

如果您使用某种外部工具来发出请求,请确保添加标题:

Content-Type: application/json


这对我有帮助,我和邮递员一起工作,谢谢哥们。
R. Gurung

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.