Express.js + body-parser:来自POST请求的空req.body

时间:2017-08-20 16:41:13

标签: javascript node.js express body-parser

我正在使用Expressbody-parser中间件来处理传入的请求。在前端,我有一个表单,它只是一个隐藏的输入和一个提交按钮(用Pug编写):

form(notes="saveNotesForm" action=`/lessons/${lesson._id}/notes` method="POST" enctype="application/x-www-form-urlencoded")
              input(type="hidden" id="hiddenNotes" name="hiddenNotes" alt="Notes Copy" value="test").notesHidden
              input(type="submit" name="saveNotes" alt="Save Notes" value="Save")

在后端,我有使用body-parser的Express应用程序:

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

处理传入请求的路由:

router.post('/lessons/:lessonID/notes', lessonController.updateNotes);

// ... and in lessonController:

exports.updateNotes = async (req, res) => {
  console.log('updateNotes request received');
  console.log(req.body);
  res.status(200).json({ status: 'success' });
}

当我尝试在req.body中使用updateNotes时,正文是一个空对象,但至少应该具有值为hiddenNotes的属性"test"。如果您有任何疑问或认为您发现问题,请发表评论!

[增订]

这是一个愚蠢的错误,我忘了我已经为这个表单提交时编写了一个单独的事件处理程序 - 它只是让我在SO上发布之后才通过我的所有代码:)事件处理程序使用{{3}看起来像这样:

const SaveNotesButton = $('form.saveNotes');
SaveNotesButton.on('submit', ajaxSaveNotes);

function ajaxSaveNotes(e) {
  e.preventDefault();
  axios
    .post(this.action)
    .then(res => {
      console.log(res.data);
    })
    .catch(console.error);
}

不幸的是,在使用axios创建post时,您需要将数据包含在这样的对象中,否则它将不会包含在请求中:

const SaveNotesButton = $('form.saveNotes');
SaveNotesButton.on('submit', ajaxSaveNotes);

function ajaxSaveNotes(e) {
  e.preventDefault();
  axios
    .post(this.action, { notes: this.children.hiddenNotes.value }) // Data added here
    .then(res => {
      console.log(res.data);
    })
    .catch(console.error);
}

3 个答案:

答案 0 :(得分:0)

是否必须尝试使用​​Postman或类似的方式查询您的终点?

答案 1 :(得分:0)

可能有一种可能的解释为什么req.body未定义。您确定在app.use(bodyParser.json())行之前写了app.use(bodyParser.url...app.use('***', router)吗?如果你在路由器中间件之后放置了身体解析器中间件,那么它基本上不会被调用,因为中间件按它们放入app.use的顺序被调用。因此,您应该将bodyParser置于所有路由器逻辑之前。 BodyParser中间件然后调用所有其他中间件(填充req.body),包括所有路由器级中间件。

希望它有所帮助!

答案 2 :(得分:0)

不确定您如何定义路线,但我希望后期路线如下所示:

const express = require('express');
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.post('/lessons/:lessonID/notes', (req, res) => {
    // now pass the req object to your function
    lessonController.updateNotes(req);
});

您需要将req对象传递给您的函数才能访问req.body ...