【问题标题】:Express.js req.body undefinedExpress.js req.body 未定义
【发布时间】:2012-02-28 22:15:58
【问题描述】:

我有这个作为我的 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 产生的第一个线程,我将在此处说明,请确保没有使用其他行为不端的中间件。

标签: node.js express


【解决方案1】:

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";。有人不应该这样做吗?
【解决方案2】:

最新版本的 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 的事情,但是在解析设置之后包括路由对我来说完全不同。
【解决方案3】:

没有。您需要在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
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

    首先确保您已经通过调用安装了名为“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呢?
    【解决方案6】:

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

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

    【讨论】:

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

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

    解决了它
    app.use(require('connect').bodyParser());
    

    而不是

    app.use(express.bodyParser());
    

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

    【讨论】:

    • @Masar 这对我不起作用。我正在使用 expressjs 4 & 我得到这样的错误。 错误:找不到模块“连接”
    • @JeyTheva mine 是一个相当古老的解决方案,因此事情可能同时发生了变化。我建议您尝试通过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 起作用。
    • application/json vs text/json 在请求中工作,正如@GrantEagon 所建议的那样。
    【解决方案8】:

    添加您的app.js

    在路由器调用之前

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

    【讨论】:

    • 我尝试了这篇文章中提到的许多解决方案。但这一个有效。在路由器之前添加 app.use(express.json())。简单的 :)。非常感谢。
    【解决方案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())
    

    【讨论】:

      【解决方案10】:

      问题已得到解答。但由于它非常通用,而且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。 [客户端] [很少] 忘记将数据与请求一起发送

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

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

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

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

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

      • 当您尝试使用form-data 格式上传文件时,有一个棘手的情况。为此,您可以使用 multer,这是一个用于处理 multipart/form-data 的中间件。

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

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

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

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

      【讨论】:

        【解决方案11】:
        app.use(express.json());
        

        有助于解决req.body undefine

        的问题

        【讨论】:

          【解决方案12】:

          看起来 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 中不起作用。
          【解决方案13】:

          如果有人遇到与我相同的问题;我正在使用像

          这样的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); 
          

          【讨论】:

            【解决方案14】:

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

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

            body-parser 可能缺少

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

            有时由于 cros 来源而未定义,所以添加它们

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

            【讨论】:

              【解决方案15】:

              中间件总是作为第一个使用。

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

              在路线之前。

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

              【讨论】:

              • 没有必要将它放在其他中间件之前(除非中间件依赖于已解析的主体,而这些示例不依赖)
              【解决方案16】:

              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
              

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

              【讨论】:

                【解决方案17】:

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

                【讨论】:

                  【解决方案18】:

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

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

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

                  【讨论】:

                  • 我的意思是,你的答案是正确的,但和其他人没有什么不同。
                  【解决方案19】:

                  在 Express 4 中,真的很简单

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

                  【讨论】:

                    【解决方案20】:

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

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

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

                    【讨论】:

                    • 该帖子提到 HTML 表单提交与 REST 客户端请求不同。两者都不是http请求吗?那么,POST 是唯一需要流式传输的情况吗?
                    【解决方案21】:

                    浪费了很多时间:

                    取决于您的客户端请求中的 Content-Type
                    server 应该有不同的,以下 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 工作正常。

                    【讨论】:

                      【解决方案22】:

                      历史:

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

                      【讨论】:

                        【解决方案23】:

                        要工作,你需要在app.use(express.bodyParser())之后app.use(app.router),像这样:

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

                        【讨论】:

                        • 你的评论和代码sn-p是矛盾的。首先,您说您必须在app.router 上使用app.use express.bodyParser,但您的代码清楚地表明它是在之后。那么它是什么?
                        • 对不起,伙计。你需要在 express.bodyParser 之后使用 app.router。
                        【解决方案24】:
                        var bodyParser = require('body-parser');
                        app.use(bodyParser.json());
                        

                        这拯救了我的一天。

                        【讨论】:

                          【解决方案25】:

                          我解决了:

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

                          【讨论】:

                            【解决方案26】:

                            在我的例子中,这是因为在包含路由之后使用了 body-parser。

                            正确的代码应该是

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

                            【讨论】:

                              【解决方案27】:

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

                              Content-Type: application/json

                              【讨论】:

                              • 这个帮助了我,我和 Postman 一起工作,谢谢哥们。
                              【解决方案28】:

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

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

                              【讨论】:

                                【解决方案29】:

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

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

                                【讨论】:

                                  【解决方案30】:

                                  当我使用 bodyParser 时,它被标记为已弃用。为避免这种情况,我将以下代码与 express 一起使用,而不是 bodyParser。

                                  注意:路由必须最终声明,这很重要!这里的其他答案很好地描述了这个问题。

                                  const express = require("express");
                                  const app = express();
                                  
                                  const routes = require('./routes/api');
                                  
                                  app.use(express.json());
                                  app.use(express.urlencoded({ extended: false }));
                                  
                                  // Routes must declared finally
                                  app.use('/', routes);
                                  

                                  【讨论】:

                                    猜你喜欢
                                    • 2012-07-03
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2016-09-05
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多