正文解析器使用另一个中间件中的bodyParser中间件

时间:2019-01-16 22:36:10

标签: javascript node.js express middleware body-parser

因此,我正在开发此Express应用程序,其中所有路线的身体尺寸均受限制,除非您是admin,因为admin需要多条路线的身体尺寸不受限制。我有limitBodySize中间件,并且正在像这样使用它:app.use(middleware.limitBodySize)

但是最终我的身体没有被解析,一切都没有定义。

limitBodySize: (req, res, next) => {
  let admin = true; // removed extra steps for simplicity

  if (admin) {
    bodyParser.urlencoded({ extended: false })(req, res, () => {
      console.log(req.body) // logs undefined
      bodyParser.json()(req, res, () => {
        console.log(req.body) // logs undefined
        next(); // in next route, console.log(req.body) logs undefined
      });
    });
  } else {
    bodyParser.urlencoded({ extended: false, limit: '1kb' })(req, res, () => {
      bodyParser.json({ limit: '1kb' })(req, res, () => {
        next();
      });
    });
  }
}

我该如何仅用一个中间件来解决这个问题,而不是通过将bodyParser中间件分别传递给每条路由或路由器来解决。

1 个答案:

答案 0 :(得分:1)

首先,您应该在自定义条件中间件之外生成bodyParser中间件,因为它可以重用。

您也不在检查错误;您的bodyParser中间件可能会为您作为next参数传递给它们的匿名回调提供错误,因此请正确处理这些错误。最简单的方法之一是使用util模块来实现每个中间件的承诺,因为无论如何您已经将它们链接在一起了。

我怀疑您的请求正文可能是JSON,并且urlencoded中间件试图将其解析失败。此时,bodyParser已经消耗了主体流,因此json中间件也可能会失败。由于您都忽略了这两个错误,因此除非您尝试执行以下操作,否则您将无法确定下一个解决方案:

const { promisify } = require('util')
const json = promisify(bodyParser.json())
const limitedJson = promisify(bodyParser.json({ limit: '1kb' }))
const urlencoded = promisify(bodyParser.urlencoded({ extended: false }))
const limitedUrlencoded = promisify(bodyParser.urlencoded({ extended: false, limit: '1kb' }))

...

limitBodySize: (req, res, next) => {
  ...

  if (admin) {
    urlencoded(req, res).then(
      () => json(req, res)
    ).then(
      () => next(),
      next
    )
  } else {
    limitedUrlencoded(req, res).then(
      () => limitedJson(req, res)
    ).then(
      () => next(),
      next
    )
  }
}

这将使用onRejected的{​​{1}}参数将任何错误传递给express框架

使用ECMAScript 2017的.then()async语法,您可以使其阅读起来更简单:

await