【问题标题】:Why is req.body undefined in Express?为什么在 Express 中 req.body 未定义?
【发布时间】:2021-03-09 21:39:32
【问题描述】:

我正在创建一个 PUT 方法来更新给定的一组数据,但是在我的更新函数中,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 });
}

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

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

【问题讨论】:

    标签: javascript node.js express knex.js


    【解决方案1】:

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

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

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

    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,用于读取这些数据类型并将其解析为您的请求处理程序可以提供的属性。

    【讨论】:

    • @alexwhitmore - 这回答了你的问题吗?
    【解决方案2】:

    您应该使用正文解析器。基本上,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
    

    【讨论】:

      【解决方案3】:

      确保您已安装 body-parser 中间件,它会提取请求流的主体并将其公开在 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())
      
      

      【讨论】:

      • 请注意,如果XMLHttpRequest使用FormData,则传入的请求表单数据需要多部分解析(npmjs.com上的multer会这样做)。
      猜你喜欢
      • 2022-01-05
      • 1970-01-01
      • 2018-11-07
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 2020-04-14
      相关资源
      最近更新 更多