ChatGPT解决这个技术问题 Extra ChatGPT

Express.js req.body 未定义

我有这个作为我的 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()); 引起的,但正如你所见,我在路由之前调用它。

有什么线索吗?

这并不是您问题的真正解决方案,但由于这是 google 产生的第一个线程,我将在此处说明,确保没有使用其他行为不端的中间件。

S
Safin Ghoghabori

2020 年 7 月更新

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

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
})

有关详细信息,请参阅 here

原文如下

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

一个例子如下:

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

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

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

这对我有用。注意:不幸的是,有些教程有人(像我一样)将路由放在 app.configure() 之前。就我而言,这是 app.get/post 等形式,以及包含它们的 require() 。
从 express 4 开始, app.use(app.router) 被删除。请参阅文档github.com/visionmedia/express/wiki/New-features-in-4.x
从 express 4 开始,像 bodyParser 这样的中间件不再与 Express 捆绑,必须单独安装。您可以在此处找到更多信息:github.com/senchalabs/connect#middleware
看起来你的第二部分是我的问题的解决方案,我有一个在正文解析器之前导入的 mail.js 模块。但很奇怪,因为我在 mail.js 本身中添加了你的 body-parser 中间件。
从 4.16.0 版开始,Express 直接从 bodyParser 公开 json() 和 urlencoded() 中间件,因此如果您只需要这两个中间件,您只需 import { json } from "express";。有人不应该这样做吗?
J
Jay

最新版本的 Express (4.x) 已将中间件从核心框架中分离出来。如果需要body parser,需要单独安装

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())

我最近更新到express 4.x。最初,当我尝试记录 req.body 时,它显示我未定义。一旦我安装并使用了 body-parser,它就会给我预期的 req.body 值。 :)
当我试图弄清楚为什么我的 POST 请求不能与 json-server 一起使用时,我发现这很有用。
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) 救了我!!
虽然这是真的,但您还必须确保在添加路由之前进行解析器配置。我已经完成了 express 4.x 的事情,但是在解析设置之后包括路由对我来说完全不同。
T
TechTurtle

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

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

d
danmactough

不可以。您需要在 app.use(app.router) 之前使用 app.use(express.bodyParser())。事实上,app.use(app.router) 应该是您调用的最后一件事。


即使在 .use 调用下移动 app.use(app.router) 也不能解决问题:(。
好的,经过一番挣扎后,我使用 app.use(require('connect').bodyParser()); 而不是 app.use(express.bodyParser()); 解决了它。
是的,即使使用 var router=express.Router(),答案也是正确的;
补充一点,你仍然应该在 app.router 之后调用错误处理中间件
未捕获的错误:大多数中间件(如 bodyParser)不再与 Express 捆绑在一起,必须单独安装。请参阅github.com/senchalabs/connect#middleware
j
jubalm

首先确保您已经通过调用安装了名为“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?
史诗般的答案兄弟,快速而有效
K
Kevin Xue

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

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


+1这对我来说是个问题。我正在使用 Postman for Chrome 来测试一个内置在 REST 中的 JSON api,但是 Express 接收到的对象每次都是空的。事实证明,即使您选择 raw > json,默认情况下 Postman 也不会自动添加“Content-Type: application/json”标头。
@Jordan +1 感谢您指出这一点。事实上,我刚刚检查了我的标题,我发现它仍然设置为'text/plain',即使我选择了'json'。
n
nbro

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

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

代替

app.use(express.bodyParser());

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


@Masar 这对我不起作用。我正在使用 expressjs 4 & 我得到这样的错误。错误:找不到模块“连接”
@JeyTheva 我的解决方案是一个非常古老的解决方案,因此事情可能同时发生了变化。我建议您尝试通过 npm install connect 安装 connect 模块并重试。通过阅读您的错误输出,这是我唯一能想到的。
以下是解决此问题的最新文档:npmjs.com/package/body-parser 对于遇到此问题“post express 4”的其他人,对我有用的是将 Content-Type 标头设置为 application/json
这是解决此问题的最新文档:npmjs.com/package/body-parser 安装 body-parser 后,它仍然无法正常工作。当我执行我的请求时,起作用的是将 Content-Type 标头设置为 application/json
正如@GrantEagon 所建议的那样,请求中的 application/jsontext/json 有效。
S
Spring

添加您的 app.js

在路由器调用之前

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

我尝试了这篇文章中提到的许多解决方案。但这一个有效。在路由器之前添加 app.use(express.json())。简单的 :)。非常感谢。
e
emkarachchi
app.use(express.json());

这将有助于解决 req.body undefined 的问题


Đ
Đăng Khoa Đinh

问题已回答。但由于它非常通用且 req.body undefined 是一个常见错误,尤其是对于初学者来说,我发现这是恢复我所知道的关于该问题的所有信息的最佳位置。

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

1. [服务器端] [经常] 忘记或误用解析器中间件

您需要使用适当的中间件来解析传入的请求。例如 express.json() 解析 JSON 格式的请求,express.urlencoded() 解析 urlencoded 格式的请求。

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

您可以在 express documentation page 中查看完整列表

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

就像其他答案指出的那样,bodyParser 自 express 4.16.0 以来已被弃用,您应该使用像上面这样的内置中间件。

2. [客户端] [很少] 忘记随请求一起发送数据

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

要验证数据是否已随请求一起发送,请在浏览器的 devtools 中打开 Network 选项卡并搜索您的请求。

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

3. [服务器和客户端] [经常] 使用不同的 Content-Type

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

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

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

最后,给全栈开发者一点建议:)

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

https://i.stack.imgur.com/wSpxm.png


P
Parwat Kunwar
// 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())

P
Praneesh

看起来 body-parser 不再随 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


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

万一有人遇到我遇到的同样问题;我正在使用像这样的 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); 

A
ANIK ISLAM SHOJIB

由于缺少 JSON 解析器,大部分时间 req.body 未定义

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

body-parser 可能会丢失

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

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

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

S
Sonali Mangrinda

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

//MIDDLEWARE
app.use(bodyParser.json());
app.use(cors());    
app.use(cookieParser());

在路线之前。

//MY ROUTES
app.use("/api", authRoutes);

不需要将它放在其他中间件之前(除非中间件依赖于已解析的主体,这些示例不依赖于)
a
ab107

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

如果你使用 curl 来执行一个在 body 中包含一些 JSON 对象的 POST 请求,它看起来像这样:

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

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


u
user1614168

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


A
Anthony Cantellano

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

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

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


我的意思是,您的答案是正确的,但与其他人没有什么不同。
M
Mayur

历史:

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

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

4.16.0 的发布历史是 here 供感兴趣的人使用,拉取请求是 here

好,回到正题,

执行:

您需要添加的只是添加,

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

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

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

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")
})

G
Gerardo Bautista

在 Express 4 中,真的很简单

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

app.use(express.json()) 

M
Masiar

这发生在我今天。以上解决方案都不适合我。但是一点谷歌搜索帮助我解决了这个问题。我正在为微信第三方服务器编码。

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

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


该帖子提到 HTML 表单提交与 REST 客户端请求不同。两者都不是http请求吗?那么,POST 是唯一需要流式传输的情况吗?
M
Manohar Reddy Poreddy

浪费了很多时间:

根据客户端请求中的 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 工作正常。


H
HenioJR

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

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

您的评论和代码片段是矛盾的。首先,您说您必须在 express.bodyParser 之前在 app.router 上使用 app.use,但您的代码清楚地表明它是 AFTER。那么它是哪一个?
对不起。你需要在 express.bodyParser 之后使用 app.router。
i
isdot
var bodyParser = require('body-parser');
app.use(bodyParser.json());

这拯救了我的一天。


K
Kkkk Kkkk

我解决了它:

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

M
Mo.

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

正确的代码应该是

app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(indexRoutes);
app.use(userRoutes);
app.use(adminRoutes);

R
Rafael Fernando Fiedler

首先,确保您在路由之前应用此中间件 (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);
});

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

而已 !


这很有帮助。我尝试了表单数据,结果总是未定义。 x-www.form-urlencoded 效果很好。
I
Inc33

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

Content-Type: application/json


这个帮助了我,我正在和 Postman 一起工作,谢谢哥们。
I
Inamur Rahman

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

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

A
Arindam

这个问题可能是因为您没有使用 body-parser (link)

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

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

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅