繁体   English   中英

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

[英]Why is req.body undefined in Express?

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

controller.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 });
}

服务.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, '*');

它应该如何看:

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

我检查评论是否存在的第一个 function 使用我的删除方法。 我是否在其中一个函数中遗漏了一些会使 req.body 未定义的东西?

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

const app = express();

...

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

...
// the rest of the express app

确保您安装了body-parser中间件,该中间件提取请求 stream 的主体并将其公开在req.body ( source )

npm install body-parser --save

下面是快速服务器定义的样子:

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())

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

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

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"

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

app.use(express.json());

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

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

要访问请求正文,您需要使用 express.json()。 确保在使用路由器之前,只需连接您的 app.use(express.json()) 即可使请求 object 可用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM