简体   繁体   English

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

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

I am creating a PUT method to update a given set of data however in my update function, req.body is undefined.我正在创建一个 PUT 方法来更新一组给定的数据,但是在我的更新 function 中,req.body 是未定义的。

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

How it should look:它应该如何看:

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

The first function where I check if a review exists work with my delete method.我检查评论是否存在的第一个 function 使用我的删除方法。 Am I missing something in one of these functions that would make req.body undefined?我是否在其中一个函数中遗漏了一些会使 req.body 未定义的东西?

You should use a body parser.您应该使用正文解析器。 Basically, Express can't know how to parse the incoming data the users throw at it, so you need to parse the data for it.基本上,Express 不知道如何解析用户扔给它的传入数据,因此您需要为它解析数据。 Luckily, there are a few body parsers (and for quite some time a body parser for JSON and UrlEncoded (not sure if there are any others) is built into Express itself).幸运的是,有一些正文解析器(在相当长的一段时间内,Express 本身内置了 JSON 和 UrlEncoded 的正文解析器(不确定是否还有其他))。 The way you do that is you add a middleware in your express app like that:你这样做的方式是在你的 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

Make sure that you have body-parser middleware installed, which extract the body of request stream and exposes it on req.body ( source )确保您安装了body-parser中间件,该中间件提取请求 stream 的主体并将其公开在req.body ( source )

npm install body-parser --save

Here's how express server definitions would look like:下面是快速服务器定义的样子:

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

Nobody in the other answers is really explaining the "why" here.其他答案中没有人真正解释这里的“为什么”。 By default req.body is undefined or empty and the Express engine does not read the body of the incoming request.默认情况下req.body undefined或为空,Express 引擎不会读取传入请求的正文。

So, if you want to know what's in the body of the request and, even further, if you want it read and then parsed into req.body so you can directly access it there, then you need to install the appropriate middleware that will see what type of request it is and if that's the type of request that has a body (like a POST or a PUT) and then it will look at the incoming content-type and see if it's a content-type that it knows how to parse, then that middleware will read the body of the request, parse it and put the parsed results into req.body so it's there when your request handler gets called.因此,如果您想知道请求正文中的内容,并且更进一步,如果您希望将其读取然后解析为req.body以便您可以在那里直接访问它,那么您需要安装将看到的适当中间件它是什么类型的请求,如果它是具有正文的请求类型(如 POST 或 PUT),然后它将查看传入的内容类型,看看它是否是它知道如何解析的内容类型,然后该中间件将读取请求的主体,对其进行解析并将解析结果放入req.body以便在调用请求处理程序时它就在那里。 If you don't have this type of middleware installed, then req.body will be undefined or empty.如果您没有安装这种类型的中间件,那么req.body将是undefined的或为空的。

Express has middleware like this built in for several content-types. Express 为多种内容类型内置了这样的中间件。 You can read about them here in the Express doc.您可以在 Express 文档中阅读有关它们的信息 There is middleware for the following content types:有以下内容类型的中间件:

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"

So, you will need some middleware to parse your specific content so you can access it in req.body .因此,您将需要一些中间件来解析您的特定内容,以便您可以在req.body中访问它。 You don't say exactly data type you're using, but from your data expectations, I would guess that perhaps it's JSON.您没有确切地说出您正在使用的数据类型,但从您的数据预期来看,我猜它可能是 JSON。 For that, you would place this:为此,您将放置以下内容:

app.use(express.json());

Somewhere before your PUT request handler.在您的 PUT 请求处理程序之前的某个地方。 If your data format is something else, then you could use one of the other built-in middleware options.如果您的数据格式是其他格式,那么您可以使用其他内置中间件选项之一。

Note, for other data types, such as file uploads and such, there are whole modules such as multer for reading and parsing those data types into properties that your request handler can offer.请注意,对于其他数据类型,例如文件上传等,有整个模块(例如multer用于读取这些数据类型并将其解析为您的请求处理程序可以提供的属性。

To get access to request body, you need to use express.json().要访问请求正文,您需要使用 express.json()。 Make sure before using router, just wire your app.use(express.json()) that should make the request object available.确保在使用路由器之前,只需连接您的 app.use(express.json()) 即可使请求 object 可用。

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

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