在 NodeJS Express 中的自定义中间件中调用第三方中间件

Calling third party middlewares inside a custom middleware in NodeJS Express

我正在学习 NodesJS Express。我正在使用 Express-Validator 进行测试。 这是我的测试程序。

const express = require("express");
const app = express();
const port = 5000;
let bodyParser = require("body-parser");

const { body, validationResult } = require("express-validator");

app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post(
  "/user",
  body("username").isEmail(),
  body("password").isLength({ min: 5 }),
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    console.log("Login successfully!");
    res.send(200);
  }
);

app.listen(port, () => {
  console.log(`Server is listening on port ${port}`);
});

当我尝试使用带有正文参数的 post 请求时:{ username:test@, password:12345a },它按我的预期工作。服务器将响应如下:

当我试图将 post 请求处理程序中的所有逻辑包装到单个中间件中时,问题发生了。当我发送相同的 post 请求时,它并没有像上面的例子那样显示错误。这意味着两个快速验证器不起作用。这是我的新程序。

const express = require("express");
const app = express();
const port = 5000;
let bodyParser = require("body-parser");

const { body, validationResult } = require("express-validator");

app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const validateEmailAndPwdlength = (req, res, next) => {
  body("username").isEmail(); // the express-validator middleware doesn't work here.
  body("password").isLength({ min: 5 });  // the express-validator middleware doesn't work here.
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  console.log("Login successfully!");
  res.sendStatus(200);
};

app.post(
  "/user",
  validateEmailAndPwdlength
);

app.listen(port, () => {
  console.log(`Server is listening on port ${port}`);
});

两个express-validator body("username").isEmail() 和 body("password").isLength({ min: 5 }) 是验证链。从 Express-Validator 文件中,它说 'The validation chain is a middleware, and it should be passed to an Express route handler'。为什么我们应该给他们放置一个 Express 路由处理程序?如果不是,我们如何在我的第二个示例中调用它们?

非常感谢您的宝贵时间!

body("username").isEmail() 的计算结果为 函数 ,如果您只是将其作为语句放在 validateEmailAndPwdlength 中,则根本没有任何效果。您可以自己调用该函数,如 (simplified)

const validateEmailAndPwdlength = (req, res, next) => {
  body("username").isEmail()(req, res, function() {
    body("password").isLength({min: 5})(req, res, function() {
      const errors = validationResult(req);
      ...
    });
  });
}

但这比您遵循 express-validator 的建议的第一个版本要长得多且可读性差(即使是在这个简化版本中)。优雅多了,有什么不喜欢的?

附录: 您可以在 Node.js 控制台中看到验证链实际上是函数:

> body("username").isEmail().toString()
'async (req, _res, next) => {\n' +
  '        try {\n' +
  '            await runner.run(req);\n' +
  '            next();\n' +
  '        }\n' +
  '        catch (e) {\n' +
  '            next(e);\n' +
  '        }\n' +
  '    }'