新的express验证器语法:验证multer处理的表单

新的express验证器语法:验证multer处理的表单,express,multer,express-validator,Express,Multer,Express Validator,所以,为了学习如何使用express.js,我正在构建一个小应用程序。我有一个非常简单的表单,同时提交一个文本字段和一个文件。这是通过FormData提交的,所以我在后端使用multer来处理请求。我想做的是在对文件执行任何操作之前对表单的文本输入执行验证(即,仅在验证成功时保存,如果不发送某种错误消息,则保存)。 我以前是这样做的 <form id="form" method='POST' enctype='multipart/form-data'> <input

所以,为了学习如何使用express.js,我正在构建一个小应用程序。我有一个非常简单的表单,同时提交一个文本字段和一个文件。这是通过FormData提交的,所以我在后端使用multer来处理请求。我想做的是在对文件执行任何操作之前对表单的文本输入执行验证(即,仅在验证成功时保存,如果不发送某种错误消息,则保存)。 我以前是这样做的

<form id="form" method='POST' enctype='multipart/form-data'>
      <input type='file' id='file-upload' name='file-upload' />
      <input type='text' id='text-upload' name='text-upload' />
      <input type='submit' />
</form>
importedController.js

//somewhere in the router file
import {importedController} from './controllers/importedController';
/* some other routes */
router.post('/upload', importedController.processfunction);
exports.processfunction = (req, res, next) => {
var getFields = multer().any();
getFields(req, res, err => {
 if (err) {return next(err);}
 req.checkBody('text-upload','must not be empty!').notEmpty();
 //do the validation from here
 var errors = req.validationErrors();
 if (errors) { 
  //some logic
 } else {
  //some other stuff
  //in both, i can access req.body and req.file to do whatever i want
 }
});
}
router.post('/upload', [ body('text-input', 'must be not empty').not().isEmpty()], importedController.processfunction);
exports.processfunction = (req, res, next) => {
 var getFields = multer().any();
 getFields(req, res, err => {
  if (err) {return next(err);}
  errors = validationResult(req);
  if (!errors.isEmpty()) {
   //actually always yields and error...
  } else { //stuff}
 });
}
但是,我注意到似乎有,因此我尝试按照以下语法执行:

router.js

//somewhere in the router file
import {importedController} from './controllers/importedController';
/* some other routes */
router.post('/upload', importedController.processfunction);
exports.processfunction = (req, res, next) => {
var getFields = multer().any();
getFields(req, res, err => {
 if (err) {return next(err);}
 req.checkBody('text-upload','must not be empty!').notEmpty();
 //do the validation from here
 var errors = req.validationErrors();
 if (errors) { 
  //some logic
 } else {
  //some other stuff
  //in both, i can access req.body and req.file to do whatever i want
 }
});
}
router.post('/upload', [ body('text-input', 'must be not empty').not().isEmpty()], importedController.processfunction);
exports.processfunction = (req, res, next) => {
 var getFields = multer().any();
 getFields(req, res, err => {
  if (err) {return next(err);}
  errors = validationResult(req);
  if (!errors.isEmpty()) {
   //actually always yields and error...
  } else { //stuff}
 });
}
但是在我的importedController.js中,验证在我定义的multer getFields()函数之外不起作用(因为请求还没有被处理,所以看起来是合乎逻辑的)。但是,如果我尝试将其包含在multer函数中:

importedController.js

//somewhere in the router file
import {importedController} from './controllers/importedController';
/* some other routes */
router.post('/upload', importedController.processfunction);
exports.processfunction = (req, res, next) => {
var getFields = multer().any();
getFields(req, res, err => {
 if (err) {return next(err);}
 req.checkBody('text-upload','must not be empty!').notEmpty();
 //do the validation from here
 var errors = req.validationErrors();
 if (errors) { 
  //some logic
 } else {
  //some other stuff
  //in both, i can access req.body and req.file to do whatever i want
 }
});
}
router.post('/upload', [ body('text-input', 'must be not empty').not().isEmpty()], importedController.processfunction);
exports.processfunction = (req, res, next) => {
 var getFields = multer().any();
 getFields(req, res, err => {
  if (err) {return next(err);}
  errors = validationResult(req);
  if (!errors.isEmpty()) {
   //actually always yields and error...
  } else { //stuff}
 });
}
然后它总是返回一个错误,尽管字段条目是正确的。就好像验证是在“未处理”的req上执行的,其中req.body为空。虽然代码现在可以工作,所以不必着急,但为了以后的项目,我还是希望遵循新语法。 非常感谢您的帮助

编辑:多亏了@gustavohenke下面的回答,我找到了一个解决方案

我意识到,归根结底,我的问题与multer模块的工作方式有关,因为它似乎在处理表单数据之前上传文件(必须在验证之前)——至少multer模块似乎无法控制它何时上传文件,在实际保存之前,您无法调用另一个中间件

因此,我最终在客户端使用ajax,首先只将表单数据发送到
multer().any()
中间件中,该中间件与表单验证器逻辑链接在一起。根据对服务器的第一次调用给出的响应,我将它与另一个ajax链接,最终将文件上传到另一个路由,这次使用
multer(存储:myStorage).single('myFileInputName')
上传文件


仔细想想,这个解决方案似乎比我一开始想的要好:它不仅避免了在表单输入错误时保存文件,甚至还避免了使用任何带宽来发送文件(这可能相当沉重)如果输入不正确。

您说验证发生在multer处理尸体之前,这是正确的

在这两种情况下,验证器都会尽快运行;但请注意以下区别:

  • 在您为遗留API提供的示例中,您在处理主体后在multer回调中定义验证。因此,它是有效的
  • 然而,在您的check API示例中,验证器是在multer有机会执行之前定义的,因此您总是会有错误-
    req.body
    仍然为空

非常感谢!正如我当时所怀疑的:)我用找到的解决方法更新了我的帖子,使用两种不同的路由和ajax将表单分两部分上传。还没有代表“公开”投票支持你,但无论如何都做了……谢谢,不用担心!继续使用express validator并发布您的反馈:)