Новый синтаксис экспресс-валидатора: форма валидации, обработанная multer

Итак, я создаю небольшое приложение, чтобы научиться использовать 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>

Серверная часть: router.js

//somewhere in the router file
import {importedController} from './controllers/importedController';
/* some other routes */
router.post('/upload', importedController.processfunction);

importController.js

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.js

router.post('/upload', [ body('text-input', 'must be not empty').not().isEmpty()], importedController.processfunction);

но тогда в моем importController.js проверка не работает вне функции multer getFields (), которую я определил (кажется логичным, поскольку запрос еще не обработан). Тем не менее, если я попытаюсь включить его в функцию multer:

importController.js

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(storage: myStorage).single('myFileInputName') для загрузки файла.

Подумав об этом, это решение кажется, возможно, лучше, чем то, о чем я думал вначале: оно не только позволяет избежать сохранения файла в случае ввода неверной формы, оно даже позволяет избежать использования любой полосы пропускания для отправки файла (что может быть довольно тяжелым) если ввод неверен.


person Nicolas Couvrat    schedule 05.09.2017    source источник


Ответы (1)


Вы правы, когда говорите, что проверка имела место до обработки тела с помощью multer.

В обоих случаях валидаторы запускаются при первой возможности; но обратите внимание на следующие отличия:

  • В примере, который вы привели для устаревшего API, вы определяете проверки внутри обратного вызова multer после обработки тела. Следовательно, это работает.
  • Однако в вашем примере API проверки валидаторы определены до возможности выполнения multer, поэтому у вас всегда будут ошибки - req.body по-прежнему пуст.
person gustavohenke    schedule 06.09.2017
comment
Большое тебе спасибо! Это было так, как я тогда подозревал :) Я обновил свой пост с помощью найденного мной обходного пути, используя два разных маршрута и ajax для загрузки формы в двух частях. У вас еще нет представителя, который мог бы "публично" проголосовать за вас, но все равно сделал ... - person Nicolas Couvrat; 10.09.2017
comment
Спасибо, не беспокойтесь! Продолжайте использовать экспресс-валидатор и оставляйте отзывы :) - person gustavohenke; 10.09.2017