req.body 在帖子上为空
Posted
技术标签:
【中文标题】req.body 在帖子上为空【英文标题】:req.body empty on posts 【发布时间】:2014-08-23 23:53:48 【问题描述】:突然之间,我所有的项目都发生了这种情况。
每当我使用 express 在 nodejs 中发帖时,body-parser req.body
是一个空对象。
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded())
// parse application/json
app.use(bodyParser.json())
app.listen(2000);
app.post("/", function (req, res)
console.log(req.body) // populated!
res.send(200, req.body);
);
通过 ajax 和邮递员,它总是空的。
但是通过 curl
$ curl -H "Content-Type: application/json" -d '"username":"xyz","password":"xyz"' http://localhost:2000/
它按预期工作。
我尝试在前者中手动设置Content-type : application/json
,但我总是得到400 bad request
这让我发疯了。
我以为是 body-parser 中更新了一些东西,但我降级了它并没有帮助。
任何帮助表示赞赏,谢谢。
【问题讨论】:
所以您尝试在邮递员中明确设置Content-Type
?如果没有,您可以尝试一下,因为我之前遇到过邮递员不发送 Content-Type
的问题。
是的,我做到了。那是我收到 400: invalid json
@mscdex - 感谢我没有在邮递员中设置 content-tupe 并且变得疯狂:)
如果你做对了所有事情,真正的答案 - ***.com/a/61802608/4010017
@kaushalpranav 链接到的内容为我修复了它!
【参考方案1】:
在可用于内容类型的 3 个选项的 Postman 中,选择“X-www-form-urlencoded”,它应该可以工作。
还要去掉错误信息替换:
app.use(bodyParser.urlencoded())
与:
app.use(bodyParser.urlencoded(
extended: true
));
见https://github.com/expressjs/body-parser
“body-parser”中间件只处理 JSON 和 urlencoded 数据,不处理多部分
正如@SujeetAgrahari 所说,body-parser 现在内置于 express.js 中。
使用 app.use(express.json());
在 JSON 正文的最新版本中实现它。对于 URL 编码的正文(由 HTTP 表单 POST 生成的那种),请使用 app.use(express.urlencoded());
【讨论】:
这适用于邮递员,我不确定为什么它适用于 ajax,因为我没有更改任何内容。 出于某种原因,通过 Angular 发布的 http 帖子不需要进行 URL 编码,但 ajax 调用却需要。有人知道为什么吗? 这对我有用,但为什么不能使用原始编码? 现在 body-parser 内置于 express.js 中,只需使用app.use(express.json());
我遇到了同样的问题。我确保我正确配置了 express 并且问题仍然存在。错误是我在发出任何请求之前在邮递员中设置了Content-Type
,当我重新启动邮递员时问题就解决了。【参考方案2】:
使用 Postman,要使用原始 JSON 数据负载测试 HTTP 发布操作,请选择 raw
选项并设置以下标头参数:
Content-Type: application/json
此外,请务必将用作 JSON 有效负载中的键/值的任何字符串用双引号括起来。
body-parser
包可以很好地解析多行原始 JSON 有效负载。
"foo": "bar"
在 Chrome v37 和 v41 中使用 Postman v0.8.4.13 扩展(body-parser
v1.12.2 和 express
v4.12.3)进行测试,设置如下:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
// configure the app to use bodyParser()
app.use(bodyParser.urlencoded(
extended: true
));
app.use(bodyParser.json());
// ... Your routes and methods here
【讨论】:
将用作键/值的任何字符串用双引号括起来......很容易错过,但否则会破坏交易!谢谢。 在 Postman 中使用form-data
发布数据时,我总是在 req.body 中得到
。我应该设置Content-Type
选项吗?【参考方案3】:
我犯了一个非常愚蠢的错误,忘记在我的 html 文件中为输入定义 name
属性。
所以不是
<input type="password" class="form-control" id="password">
我有这个。
<input type="password" class="form-control" id="password" name="password">
现在request.body
填充如下: password: 'hhiiii'
【讨论】:
这是我的问题,谢谢指出【参考方案4】:我发现,它在使用内容类型发送时有效
“应用程序/json”
结合服务器端
app.use(bodyParser.json());
现在我可以通过发送了
var data = name:"John"
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", theUrl, false); // false for synchronous request
xmlHttp.setRequestHeader("Content-type", "application/json");
xmlHttp.send(data);
结果在服务器上的request.body.name
中可用。
【讨论】:
感谢您的支持。我真的认为这是最干净的,虽然不是最简单的解决方案,因为无论如何你都应该发送正确的内容类型。我想。 就我而言,我必须将其更改为xmlHttp.send(JSON.stringify(data));
什么是bodyParser,它从何而来?
@AmbroiseRabier 它是在原始问题中的 express.js 之后立即导入的。所以基本上是一个外部库。【参考方案5】:
您必须检查 body-parser 中间件是否正确设置为请求类型(json,urlencoded)。
如果你已经设置了,
app.use(bodyParser.json());
然后在邮递员中,您必须将数据作为原始数据发送。
https://i.stack.imgur.com/k9IdQ.png邮递员截图
如果你已经设置了,
app.use(bodyParser.urlencoded(
extended: true
));
然后应该选择“x-www-form-urlencoded”选项。
【讨论】:
两者兼得怎么样? (bodyParser.urlencoded 和 bodyParser.json())... postman 可以用哪一个?【参考方案6】:我今天遇到了这个问题,解决方法是在 Postman 中删除 content-type 标头!很奇怪。在这里添加它以防它帮助某人。
我在这里学习 BeerLocker 教程:http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/
【讨论】:
我遇到了同样的问题。将标题“未选中”(并变灰)是不够的,我必须完全删除它。即使“>”源按钮显示我没有发送 Content-Type 处于未选中状态的标头,它仍然需要完全删除。 我不知道如何删除邮递员 chrome 扩展程序中的默认标题...您是否正在使用该应用程序? 哦,我安装了该应用程序,它比扩展程序好得多。抱歉打扰了。【参考方案7】:如果是邮递员,请在请求API时确认这些内容
【讨论】:
【参考方案8】:我的问题是我先创建路线
// ...
router.get('/post/data', myController.postHandler);
// ...
并在路由之后注册中间件
app.use(bodyParser.json());
//etc
由于应用程序结构和从示例中复制和粘贴项目。
一旦我确定了在路由之前注册中间件的顺序,一切都奏效了。
【讨论】:
【参考方案9】:对于 express 4.16+,不需要安装 body-parser,使用如下:
const express = require('express');
const app = express();
app.use(express.json());
app.post('/your/path', (req, res) =>
const body = req.body;
...
【讨论】:
为我解决了。使用它来获取 PUT 请求的主体。body-parser
返回空 json 正文【参考方案10】:
在邮递员中,即使遵循接受的答案,我也收到了一个空的请求正文。问题原来是没有传递一个名为
的标题Content-Length : <calculated when request is sent>
此标头默认存在(以及其他 5 个),但我已禁用。启用此功能,您将收到请求正文。
【讨论】:
【参考方案11】:发出邮递员请求时,错误源未定义特定的标头类型。我只是通过添加来解决它
Content-Type: application/json
或者在发出请求的同时在邮递员中明确定义原始数据类型为 JSON 也可以解决问题。
【讨论】:
在发出 Postman 请求时必须检查Content-Lenght
。否则会抛出错误。
@ghimirehillson 的解决方案解决了我的问题【参考方案12】:
Express 4.17.1
没有bodyParser
的服务器中间件示例;
app.use(express.json());
app.use(express.urlencoded( extended: true ));
如果你是GET请求头应该是这样的;
'Content-Type': 'application/json'
如果你是 POST 请求的标头应该是这样的;
'Content-Type': 'application/x-www-form-urlencoded'
我在客户端使用这样的简单功能;
async function _GET(api)
return await (await fetch(api,
method: 'GET',
mode: 'no-cors',
cache: 'no-cache',
credentials: 'same-origin',
headers:
'Content-Type': 'application/json; charset=utf-8',
'Connection': 'keep-alive',
'Accept': '*',
,
)).json();
;
async function _POST (api, payload)
return await (await fetch(api,
method: 'POST',
mode: 'no-cors',
cache: 'no-cache',
credentials: 'same-origin',
headers:
'Content-Type': 'application/x-www-form-urlencoded',
'Connection': 'keep-alive',
'Accept': '*/*',
,
body: new URLSearchParams(payload),
)).json();
;
【讨论】:
【参考方案13】:即使当我第一次学习 node.js 时,我开始通过网络应用程序学习它,我在我的表单中以很好的方式完成了所有这些事情,但我仍然无法在发布请求中接收值.经过长时间的调试,我知道在我提供enctype="multipart/form-data"
的表单中,我无法获取值。我只是删除了它,它对我有用。
【讨论】:
是的,这也可以获取表单主体但是然后导致我的表单出现另一个问题-基本上无法上传文件,因为这需要enctype="multipart/form-data"
顺便说一句,只是为了添加到我上面的评论中,我设法与multer
一起工作 - 请参阅npmjs.com/package/multer 上的文档【参考方案14】:
我按照上面的建议使用multer
解决了这个问题,但是他们没有给出一个完整的工作示例,说明如何做到这一点。基本上,当您有一个带有enctype="multipart/form-data"
的表单组时,就会发生这种情况。这是我的表单的 HTML:
<form action="/stats" enctype="multipart/form-data" method="post">
<div class="form-group">
<input type="file" class="form-control-file" name="uploaded_file">
<input type="text" class="form-control" placeholder="Number of speakers" name="nspeakers">
<input type="submit" value="Get me the stats!" class="btn btn-default">
</div>
</form>
下面是如何使用multer
来获取此表单的值和名称,Express.js
和node.js
:
var multer = require('multer')
var upload = multer( dest: './public/data/uploads/' )
app.post('/stats', upload.single('uploaded_file'), function (req, res)
// req.file is the name of your file in the form above, here 'uploaded_file'
// req.body will hold the text fields, if there were any
console.log(req.file, req.body)
);
【讨论】:
【参考方案15】:似乎如果您不使用任何 encType(默认为 application/x-www-form-urlencoded
),那么您确实会获得文本输入字段,但您不会获得文件。
如果您有一个要发布文本输入和文件的表单,则使用multipart/form-data
编码类型,除此之外使用multer
中间件。 Multer 将解析请求对象并为您准备req.file
,所有其他输入字段将通过req.body
提供。
【讨论】:
谢谢 -multer
确实是我的问题的解决方案。如果您可以添加一个示例,说明如何将其用作答案的一部分,那就太好了【参考方案16】:
相信这个可以解决app.use(express.json());
【讨论】:
【参考方案17】:我也遇到过类似的问题,我只是把回调参数的顺序搞混了。确保您以正确的顺序设置回调函数。至少对于遇到同样问题的人来说。
router.post('/', function(req, res));
【讨论】:
我解决了我的问题,删除任何 express.json() express.urlencode() 或 bady-parse 并编写 app.post('/path',function(req,res) data=" " // 我们可以访问 HTTP 头 req.on('data', chunk => data+=chunk ) req.on('end', () => console.log(data) js=JSON.parse(数据) ) )【参考方案18】:确保 ["key" : "type", "value" : "json"] & ["key":"Content-Type", "value":"application/x-www-form-urlencoded"]在您的邮递员请求标头中
【讨论】:
【参考方案19】:我的输入中没有名字……我的请求是空的……很高兴已经完成,我可以继续编码。谢谢大家!
Jason Kim 使用的答案:
所以不是
<input type="password" class="form-control" id="password">
我有这个
<input type="password" class="form-control" id="password" name="password">
【讨论】:
【参考方案20】:几分钟前我遇到了同样的问题,我在上述答案中尝试了所有可能的方法,但其中任何一个都有效。
我唯一做的就是升级Node JS版本,我不知道升级会影响什么,但确实如此。
我已经安装了 Node JS 版本10.15.0
(最新版本),我回到了8.11.3
,现在一切正常。也许body-parser
模块应该解决这个问题。
【讨论】:
【参考方案21】:您不应该在通过 AJAX 发送时使用JSON.stringify(data)
,如下所示。
这不是正确的代码:
function callAjax(url, data)
$.ajax(
url: url,
type: "POST",
data: JSON.stringify(data),
success: function(d)
alert("successs "+ JSON.stringify(d));
);
正确的代码是:
function callAjax(url, data)
$.ajax(
url: url,
type: "POST",
data: data,
success: function(d)
alert("successs "+ JSON.stringify(d));
);
【讨论】:
这里要注意的关键一点是,在类型中,请确保将“POST”大写。我见过仅使用“post”导致空白 req.body 的实例。【参考方案22】:我的问题是先创建路线
require("./routes/routes")(app);
我之前把它移到了代码的末尾
app.listen
并且成功了!
【讨论】:
【参考方案23】:我通过在前端更改表单的 enctype 解决了这个问题:
原来是⛔️<form enctype="multipart/form-data">
我把它改成了✅<form enctype="application/json">
看到数据最终弹出到控制台,我松了一口气^^
【讨论】:
【参考方案24】:当表单不包含任何文件上传输入时,请确保您已删除表单标记处的 enctype 属性
enctype='multipart/form-data
【讨论】:
【参考方案25】:我使用的是 restify 而不是 express 并遇到了同样的问题。解决方案是:
server.use(restify.bodyParser());
【讨论】:
【参考方案26】:将代码中的app.use(bodyParser.urlencoded());
更改为
app.use(bodyParser.urlencoded(extended : false));
在邮递员中,在标头中将 Content-Type
值从
application/x-www-form-urlencoded
到 application/json
Ta:-)
【讨论】:
【参考方案27】:感谢大家的精彩回答!
花了相当长的时间寻找解决方案,而在我这边,我犯了一个基本错误:我从函数内部调用bodyParser.json()
:
app.use(['/password'], async (req, res, next) =>
bodyParser.json()
/.../
next()
)
我只需要做app.use(['/password'], bodyParser.json())
就可以了...
【讨论】:
【参考方案28】:在我的例子中,我使用 Fetch API 发送 POST 请求,在正文中,我发送的是对象而不是字符串。
错误 -> body: email: 'value'
我通过对正文进行字符串化来纠正 -> body: JSON.stringify( email: 'value' )
【讨论】:
【参考方案29】:只是快速输入 - 我遇到了同样的问题(用失眠症测试我的私人 api),当我添加 Content-Type: application/json 时,它立即工作。让我感到困惑的是,对于 GET 和 POST 请求,我所做的一切几乎都是相同的,但 PUT 似乎不起作用。我真的很希望这有助于让某人摆脱调试的兔子洞!
【讨论】:
【参考方案30】:检查您的 HTML 标记名称属性
<input name="fname">
body-parser 使用标签名称属性来识别标签。
【讨论】:
以上是关于req.body 在帖子上为空的主要内容,如果未能解决你的问题,请参考以下文章
即使在 node.js 应用程序中使用 body-parser(使用 CORS 和 HTTPS),req.body 在 POST 中仍然为空