为什么 Express 中 req.body 未定义?

4 javascript node.js express knex.js

我正在创建一个 PUT 方法来更新给定的数据集,但是在我的更新函数中, req.body 未定义。

控制器.js

async function reviewExists(req, res, next) {
  const message = { error: `Review cannot be found.` };
  const { reviewId } = req.params;
  if (!reviewId) return next(message);
  let review = await ReviewsService.getReviewById(reviewId);
  if (!review) {
    return res.status(404).json(message);
  }
  res.locals.review = review;
  next();
}

async function update(req, res, next) {
  console.log(req.body);
  const knexInstance = req.app.get('db');
  const {
    review: { review_id: reviewId, ...review },
  } = res.locals;

  const updatedReview = { ...review, ...req.body.data };

  const newReview = await ReviewsService.updateReview(
    reviewId,
    updatedReview,
    knexInstance
  );
  res.json({ data: newReview });
}
Run Code Online (Sandbox Code Playgroud)

服务.js

const getReviewById = (reviewId) =>
  knex('reviews').select('*').where({ review_id: reviewId }).first();

const updateReview = (reviewId, updatedReview) =>
  knex('reviews')
    .select('*')
    .where({ review_id: reviewId })
    .update(updatedReview, '*');
Run Code Online (Sandbox Code Playgroud)

它应该是什么样子:

"data": {
    "review_id": 1,
    "content": "New content...",
    "score": 3,
    "created_at": "2021-02-23T20:48:13.315Z",
    "updated_at": "2021-02-23T20:48:13.315Z",
    "critic_id": 1,
    "movie_id": 1,
    "critic": {
      "critic_id": 1,
      "preferred_name": "Chana",
      "surname": "Gibson",
      "organization_name": "Film Frenzy",
      "created_at": "2021-02-23T20:48:13.308Z",
      "updated_at": "2021-02-23T20:48:13.308Z"
    }
Run Code Online (Sandbox Code Playgroud)

我检查评论是否存在的第一个函数与我的删除方法一起使用。我是否在这些函数之一中遗漏了一些导致 req.body 未定义的内容?

jfr*_*d00 18

其他答案中没有人真正解释这里的“原因”。默认情况下req.bodyundefined空,Express 引擎不会读取传入请求的正文。

因此,如果您想知道请求正文中的内容,甚至更进一步,如果您希望读取它然后解析它req.body以便您可以直接访问它,那么您需要安装适当的中间件来查看什么类型请求它,如果这是具有正文的请求类型(例如 POST 或 PUT),然后它将查看传入的内容类型并查看它是否是它知道如何解析的内容类型,然后中间件将读取请求的正文,解析它并将解析的结果放入其中,req.body以便在调用请求处理程序时它就在那里。如果您没有安装此类中间件,则将req.bodyundefined空。

Express 为多种内容类型内置了类似的中间件。您可以在 Express 文档中阅读有关它们的信息。有适用于以下内容类型的中间件:

express.json(...)    for "application/json"
express.raw(...)     reads the body into a Buffer for you to parse yourself
express.text(...)    for "text/plain" - reads the body into a string
express.urlencoded(...) for "application/x-www-form-urlencoded"
Run Code Online (Sandbox Code Playgroud)

因此,您将需要一些中间件来解析您的特定内容,以便您可以在req.body. 您没有确切地说您正在使用的数据类型,但从您的数据期望来看,我猜它可能是 JSON。为此,您可以放置​​以下内容:

app.use(express.json());
Run Code Online (Sandbox Code Playgroud)

在 PUT 请求处理程序之前的某个位置。如果您的数据格式是其他格式,那么您可以使用其他内置中间件选项之一。

请注意,对于其他数据类型,例如文件上传等,有完整的模块,例如multer用于读取这些数据类型并将其解析为请求处理程序可以提供的属性。


Top*_*oEU 7

您应该使用主体解析器。基本上,Express 不知道如何解析用户向其输入的传入数据,因此您需要为其解析数据。幸运的是,有一些主体解析器(并且在相当长的一段时间内,JSON 和 UrlEncoded 的主体解析器(不确定是否还有其他解析器)内置于 Express 本身中)。这样做的方法是在 Express 应用程序中添加一个中间件,如下所示:

const app = express();

...

app.use(express.json({
    type: "*/*" // optional, only if you want to be sure that everything is parsed as JSON. Wouldn't recommend
}));

...
// the rest of the express app
Run Code Online (Sandbox Code Playgroud)