Express.js req.body undefined

Mas*_*iar 248 node.js express

我有这个作为我的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());
Run Code Online (Sandbox Code Playgroud)

但是当我req.body.something在我的路线中要求时,我会得到一些错误指出body is undefined.以下是使用req.body以下路线的示例:

app.post('/admin', function(req, res){
    console.log(req.body.name);
});
Run Code Online (Sandbox Code Playgroud)

我读到这个问题是由于缺乏而引起的,app.use(express.bodyParser());但是你可以看到我在路线之前调用它.

任何线索?

Mar*_*ano 266

您必须确保在定义路径之前定义所有配置.如果您这样做,您可以继续使用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' });
});
Run Code Online (Sandbox Code Playgroud)

  • 从快递4开始,像bodyParser这样的中间件不再与Express捆绑在一起,必须单独安装.您可以在这里找到更多信息:https://github.com/senchalabs/connect#middleware. (14认同)
  • 从快递4开始,app.use(app.router)被删除.请参阅文档https://github.com/visionmedia/express/wiki/New-features-in-4.x (10认同)
  • 这对我有用.注意:不幸的是,有些教程有人(比如我)在app.configure()之前放置路由.在我的情况下,这是app.get/post等形式,以及包含它们的require(). (7认同)
  • 谢谢。这个答案已经超过 2 年了,仍然不断地帮助有困难的人:) (4认同)
  • 从版本 4.16.0 开始,Express 直接从 bodyParser 公开 json() 和 urlencoded() 中间件,因此如果您只需要这两个中间件,您可以直接 `import { json } from "express";` 。有人不应该这样做吗? (3认同)
  • 哇。这是一个很大的更新。非常感谢您的更新 (2认同)

Jay*_*Jay 240

最新版本的Express(4.x)已从核心框架中分离出中间件.如果您需要身体解析器,则需要单独安装它

npm install body-parser --save
Run Code Online (Sandbox Code Playgroud)

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

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())
Run Code Online (Sandbox Code Playgroud)

  • `app.use(bodyParser.urlencoded({extended: false })); app.use(bodyParser.json())` 救了我!! (3认同)
  • 我最近更新为表达4.x。最初,当我尝试登录req.body时,它向我显示未定义。一旦我安装并使用了body解析器,它就会为我提供预期的req.body值。:) (2认同)
  • 虽然这是真的,但您还必须确保在添加路由之前进行解析器配置。我已经完成了 express 4.x 的事情,但是在解析设置之后包括路由对我来说完全不同。 (2认同)

dan*_*ugh 64

第您需要使用app.use(express.bodyParser())之前app.use(app.router).事实上,app.use(app.router)应该是你打电话的最后一件事.


小智 39

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

npm install body-parser --save
Run Code Online (Sandbox Code Playgroud)

然后确保在调用路由之前包含以下行

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

app.use(bodyParser.json());
Run Code Online (Sandbox Code Playgroud)


Kev*_*Xue 34

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

确保你使用的是像application/x-www-form-urlencoded,application/json或其他东西,它取决于你的帖子数据.将此字段留空会使Express混淆.

  • +1这对我来说是个问题.我使用Postman for Chrome来测试REST中构建的JSON api,但Express收到的对象每次都是空的.默认情况下输出Postman****不会**自动添加'Content-Type:application/json'标题,即使你选择raw> json也是如此. (11认同)

Mas*_*iar 33

正如在一条评论中发布的那样,我用它来解决它

app.use(require('connect').bodyParser());
Run Code Online (Sandbox Code Playgroud)

代替

app.use(express.bodyParser());
Run Code Online (Sandbox Code Playgroud)

我还是不知道为什么简单express.bodyParser()不起作用......

  • 以下是解决此问题的最新文档:https://www.npmjs.com/package/body-parser对于遇到此问题的其他人"post express 4",对我有用的是将`Content-Type`标题设置为`应用/ json`. (3认同)
  • 以下是解决此问题的最新文档:https://www.npmjs.com/package/body-parser安装了body-parser之后,它仍然无效.当我做我的请求时,做什么工作是将`Content-Type`标题设置为`application/json`. (3认同)

Tec*_*tle 27

Express 4,内置了body解析器.无需安装单独的body-parser.以下将起作用:

export const app = express();
app.use(express.json());
Run Code Online (Sandbox Code Playgroud)

  • 这必须是我接受的答案 (4认同)

小智 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())
Run Code Online (Sandbox Code Playgroud)


小智 16

app.use(express.json());
Run Code Online (Sandbox Code Playgroud)

它将有助于解决req.body undefine的问题


kin*_*neo 11

大多数时候 req.body 由于缺少 JSON 解析器而未定义

const express = require('express');
app.use(express.json());
Run Code Online (Sandbox Code Playgroud)

身体解析器可能会丢失

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

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

const cors = require('cors');
app.use(cors())
Run Code Online (Sandbox Code Playgroud)


Đăn*_*inh 11

问题得到解答。但是由于它非常通用并且req.bodyundefined 是一个常见的错误,特别是对于初学者来说,我发现这是恢复我对问题的所有了解的最佳场所。


此错误可能由以下原因引起:

1.【SERVER端】忘记或误用解析器中间件

  • 您需要使用适当的中间件来解析传入的请求。比如express.json()解析JSON格式的express.urlencoded()请求,解析urlencoded格式的请求。
const app = express();
app.use(express.urlencoded())
app.use(express.json())
Run Code Online (Sandbox Code Playgroud)

您可以在快速文档页面中查看完整列表

  • 您应该在路由声明部分之前使用解析器中间件(我做了一个测试来确认这一点!)。中间件可以在初始化 express 应用程序后立即配置。

  • 就像其他答案指出的那样,自 express 4.16.0 以来不推荐使用 bodyParser,您应该使用上述内置中间件。

2. [CLIENT side] 忘记随请求一起发送数据

  • 嗯,你需要发送数据...

要验证数据是否与请求一起发送,请打开浏览器开发工具中的网络选项卡并搜索您的请求。

  • 这很少见,但我看到有些人试图在GET请求中发送数据,因为 GET 请求req.body未定义。

3. [SERVER & CLIENT] 使用不同的 Content-Type

  • 服务器和客户端需要使用相同的 Content-Type来相互理解。如果使用json格式发送请求,则需要使用json()中间件。如果您使用urlencoded格式发送请求,则需要使用urlencoded()...

  • 当您尝试使用该格式上传文件时,有一种棘手的情况form-data。为此,您可以使用multer,一个用于处理多部分/表单数据的中间件。

  • 如果您不控制客户端部分怎么办?我在为支付 IPN编写 API 时遇到了问题。一般规则是尝试获取客户端部分的信息:与前端团队沟通,转到支付文档页面......您可能需要根据客户端部分决定的 Content-Type 添加适当的中间件。

最后,给全栈开发人员的一条建议:)

遇到这样的问题,可以尝试使用一些API测试软件,比如Postman。目的是消除客户端部分的所有噪音,这将有助于您正确识别问题。

在 Postman 中,一旦得到正确的结果,就可以使用软件中的代码生成工具来生成对应的代码。该按钮</>位于右侧栏上。你有很多流行语言/库的选择...... 在此处输入图片说明


Pra*_*esh 10

看起来身体解析器不再附带快递.我们可能需要单独安装它.

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!
Run Code Online (Sandbox Code Playgroud)

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


Jef*_*ley 10

如果有人碰到我遇到的同样问题; 我使用的是url前缀

http://example.com/api/
Run Code Online (Sandbox Code Playgroud)

这是用路由器设置的

app.use('/api', router); 
Run Code Online (Sandbox Code Playgroud)

然后我有以下

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
Run Code Online (Sandbox Code Playgroud)

解决我的问题的原因是上面放置了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); 
Run Code Online (Sandbox Code Playgroud)


小智 10

加入您的 app.js

在路由器呼叫之前

const app = express();
app.use(express.json());
Run Code Online (Sandbox Code Playgroud)

  • 你救了我的命,伙计!关键是在呼叫路由器之前添加线路 (5认同)

小智 9

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

如果您使用curl执行包含正文中的某个JSON对象的POST请求,它将如下所示:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute
Run Code Online (Sandbox Code Playgroud)

如果使用其他方法,只需确保使用适当的约定设置该标题字段.


小智 9

中间件始终作为第一个使用。

//MIDDLEWARE
app.use(bodyParser.json());
app.use(cors());    
app.use(cookieParser());
Run Code Online (Sandbox Code Playgroud)

在路线之前。

//MY ROUTES
app.use("/api", authRoutes);
Run Code Online (Sandbox Code Playgroud)


May*_*yur 9

历史:

Express 的早期版本曾经捆绑了很多中间件。bodyParser是它附带的中间件之一。当 Express 4.0 发布时,他们决定从 Express 中删除捆绑的中间件,并将它们制成单独的包。安装模块后,语法从app.use(express.json())变为。app.use(bodyParser.json())bodyParser

bodyParser在 4.16.0 版本中被重新添加到 Express 中,因为人们希望它像以前一样与 Express 捆绑在一起。bodyParser.json()这意味着如果您使用的是最新版本,则无需再使用。你可以用express.json()它代替。

有兴趣的人可以在这里查看 4.16.0 的发布历史记录,也可以在这里获取拉取请求。

好了,回到正题,

执行:

您只需添加即可,

app.use(express.json());
app.use(express.urlencoded({ extended: true}));
app.use(app.router); // Route will be at the end of parser
Run Code Online (Sandbox Code Playgroud)

并删除bodyParser(在较新版本的express中不需要)

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
Run Code Online (Sandbox Code Playgroud)

Express 将满足您的要求。:)

完整的例子看起来像,

const express       = require('express')
const app           = express()

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

app.post('/test-url', (req, res) => {
    console.log(req.body)
    return res.send("went well")
})

app.listen(3000, () => {
    console.log("running on port 3000")
})
Run Code Online (Sandbox Code Playgroud)


Raf*_*ler 9

首先,确保您(express.urlencoded)在路由之前应用此中间件。

let app = express();

//response as Json
app.use(express.json()); 

//Parse x-www-form-urlencoded request into req.body
app.use(express.urlencoded({ extended: true }));     

app.post('/test',(req,res)=>{
    res.json(req.body);
});
Run Code Online (Sandbox Code Playgroud)

该代码express.urlencoded({extended:true})仅响应x-www-form-urlencoded posts请求,因此在ajax/XMLHttpRequest/fetch中,请确保发送request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');标头。

就是这样 !


小智 8

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

app.use(bodyParser.urlencoded({extended: true}));
Run Code Online (Sandbox Code Playgroud)

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


Ger*_*sta 7

在 Express 4 中,它真的很简单

const app = express()
const p = process.env.PORT || 8082

app.use(express.json()) 
Run Code Online (Sandbox Code Playgroud)


Man*_*ddy 6

浪费了很多时间:

根据客户端请求中
的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' }))
Run Code Online (Sandbox Code Playgroud)

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

例子:

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

Content-Type: "text/xml"
Run Code Online (Sandbox Code Playgroud)

所以,在服务器端,我使用了:

app.use(bodyParser.text({type: 'text/xml'}));
Run Code Online (Sandbox Code Playgroud)

然后, req.body 工作正常。


小智 6

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


Hic*_*adi 6

当我遇到同样的问题时,尽管我知道BodyParser不再使用并且我已经使用了app.use(express.json()) 问题是{FOR ME}:我正在放置

app.use(express.json())

app.use('api/v1/example', example) => {关注路线}

一旦我重新排序这两行;

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

2 -app.use('api/v1/example', example)

效果很好


Hen*_*oJR 5

为了工作,你需要app.use(app.router)app.use(express.bodyParser()) ,这样的:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);
Run Code Online (Sandbox Code Playgroud)

  • 对不起。您需要在express.bodyParser之后使用app.router。 (2认同)

spi*_*ang 5

这发生在我今天.以上解决方案均不适合我.但是一点点谷歌搜索帮我解决了这个问题.我正在编写wechat第三方服务器.

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

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


小智 5

var bodyParser = require('body-parser');
app.use(bodyParser.json());
Run Code Online (Sandbox Code Playgroud)

这挽救了我的一天。


小智 5

我用以下方法解决了它:

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


ari*_*ari 5

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

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

var app = express();
app.use(bodyParser.json());
Run Code Online (Sandbox Code Playgroud)


小智 5

就我而言,这是因为在包含路线后使用了主体解析器。

正确的代码应该是

app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(indexRoutes);
app.use(userRoutes);
app.use(adminRoutes);
Run Code Online (Sandbox Code Playgroud)