Итак, я создаю небольшое приложение, чтобы научиться использовать 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')
для загрузки файла.
Подумав об этом, это решение кажется, возможно, лучше, чем то, о чем я думал вначале: оно не только позволяет избежать сохранения файла в случае ввода неверной формы, оно даже позволяет избежать использования любой полосы пропускания для отправки файла (что может быть довольно тяжелым) если ввод неверен.