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()); |
但是当我在路线中要求
1 2 3 | app.post('/admin', function(req, res){ console.log(req.body.name); }); |
我读到这个问题是由于缺少
有什么线索吗?
2020年7月更新
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 }) |
看到这里了解更多信息
原始跟随
您必须确保在定义路由之前定义所有配置。如果这样做,您可以继续使用
示例如下:
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()) |
否。您需要在
首先,请确保通过调用以下命令安装了名为" 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()); |
我仍然不知道为什么简单的
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()) |
添加您的
在路由器呼叫之前
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配置放在
最后
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()); |
到您的
归功于@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()); |
如果您使用某种外部工具来发出请求,请确保添加标题:
将
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,但是
未定义现在更改为对象。根据Express文档,如果
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未定义的问题