关于node.js:Express.js req.body未定义

Express.js req.body undefined

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

1
2
3
4
5
6
7
8
9
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的路由的示例:

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

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

有什么线索吗?


2020年7月更新

express.bodyParser()不再捆绑为express的一部分。您需要在加载之前单独安装它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
npm i body-parser

// then in your app
var express = require('express')
var bodyParser = require('body-parser')
 
var app = express()
 
// create application/json parser
var jsonParser = bodyParser.json()
 
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
 
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
  res.send('welcome, ' + req.body.username)
})
 
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
  // create user in req.body
})

看到这里了解更多信息

原始跟随

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

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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' });
});


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

1
npm install body-parser --save

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

1
2
3
4
5
6
7
8
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())


否。您需要在app.use(app.router)之前使用app.use(express.bodyParser())。实际上,app.use(app.router)应该是您最后调用的东西。


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

1
npm install body-parser --save

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

1
2
3
4
5
var express = require('express');
var bodyParser = require('body-parser');
var app = express();

app.use(bodyParser.json());


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

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

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

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


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

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

代替

1
app.use(express.bodyParser());

我仍然不知道为什么简单的express.bodyParser()无法正常工作...


1
2
3
4
5
6
7
8
9
// 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())

添加您的app.js

在路由器呼叫之前

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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。


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

1
http://example.com/api/

用路由器设置的

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

然后我有以下

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

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

最后

1
2
3
4
5
6
// 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);

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

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

可能缺少人体分析器

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

有时由于cro的来源而不确定,因此请添加它们

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

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


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

如果您使用curl来执行POST请求,该请求在主体中包含一些JSON对象,则它将类似于以下内容:

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

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


您可以尝试在顶部添加以下代码行(在您的require语句之后):

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

至于它为什么起作用的原因,请查看文档:https://www.npmjs.com/package/body-parser#bodyparserurlencodedoptions


在Express 4中,这非常简单

1
2
3
4
const app = express()
const p = process.env.PORT || 8082

app.use(express.json())

浪费了很多时间:

根据客户请求中的内容类型
服务器应具有以下app.use()之一:

1
2
3
4
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

例:

为了我,
在客户端,我有以下标题:

1
Content-Type:"text/xml"

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

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

然后,req.body工作正常。


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

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

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


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

这挽救了我的一天。


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

1
2
3
app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);


我解决了:

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

此问题可能是因为您没有使用body-parser(链接)

1
2
3
4
5
var express = require('express');
var bodyParser  = require('body-parser');

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

这也是一种可能性:确保在app.js(或index.js)文件中的路由之前编写此代码。

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

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

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

就我而言,这是因为在包含路线之后使用了body-parser。

正确的代码应该是

1
2
3
4
5
app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(indexRoutes);
app.use(userRoutes);
app.use(adminRoutes);


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

1
2
3
4
5
var express = require('express');
var app = express();
var bodyParser = require('body-parser');

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

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

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

1
2
3
4
5
6
7
8
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());

对于以上答案均无济于事的任何人,我都必须在前端和Express之间启用cors。

您可以通过以下方式进行此操作:

  • 为您的浏览器下载并打开CORS扩展程序,例如:

    https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=zh-CN

    对于Chrome,

  • 添加行

    1
    2
    3
    var cors=require('cors');

    app.use(cors());
  • 到您的app.js快速页面。 (在npm install cors之后)


    归功于@spikeyang的出色回答(下面提供)。阅读该帖子所附的建议文章后,我决定分享我的解决方案。

    什么时候使用?

    该解决方案要求您使用快速路由器才能使用它。
    如果您尝试使用接受的答案但没有运气,则只需使用以下功能即可复制并粘贴:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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);
        });
    }

    并这样称呼它:

    1
    2
    3
    4
    5
    6
    7
    bodyParse(req, function success(body)
    {

    }, function error(message)
    {

    });

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


    最新版本的Express已经内置了body-parser。因此,您可以使用:

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

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

    Content-Type: application/json


    express.urlencoded({ extended: true })添加到路由即可解决此问题。

    1
    router.post('/save',express.urlencoded({ extended: true }), "your route");

    我的是文本输入,无论如何,我都会在此处添加此答案,以便对人们有所帮助。解析时请确保设置了编码!在为它设置适当的值之前,我一直在努力使其发挥作用。

    这是我不使用任何解析器而得到的错误:

    1
    2
    3
    error info: TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object.

    Received an instance of undefined at Function.from (buffer.js:327:9)

    我们现在不必像其他人已经提到的那样在Express中使用body-parser,但是app.use(express.text());并不能解决我的问题。

    未定义现在更改为对象。根据Express文档,如果Content-Type不匹配(以及其他),请求正文将返回一个空对象({})。

    1
    2
    3
    error info: TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object.

    Received an instance of Object at Function.from (buffer.js:327:9)

    您设置的编码类型也必须在点上。就我而言,它是文本/纯文本。您可以更改它以满足您的需求,例如JSON等。我做到了,瞧!像魅力一样工作!

    1
    2
    3
    app.use(express.text({
        type:"text/plain"
    }));

    当您忘记输入元素中的name属性时,获取空request.body的另一种可能方法...

    1
    2
    <input type="text" /> /* give back empty request.body -> {}*/
    <input type="text" name="username" /> /* give back request.body -> {"username":"your-input"} */

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

    这将有助于解决req.body未定义的问题