新的快速验证器语法:验证由 multer 处理的表单
New express-validator syntax : validate form processed by multer
因此,我正在构建一个小应用程序以学习如何使用 express.js。我有一个非常简单的表单,同时提交一个文本字段和一个文件。这是通过 FormData 提交的,所以我在后端使用 multer 来处理请求。我想做的是对表单的文本输入执行验证 BEFORE 对文件采取任何行动(即仅在验证成功时保存,如果不发送某种错误消息) .
我以前就是这样做的
<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);
importedController.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
}
});
}
不过我注意到似乎有 a new syntax for express validator,所以我尝试遵循此语法并执行以下操作:
router.js
router.post('/upload', [ body('text-input', 'must be not empty').not().isEmpty()], importedController.processfunction);
但是在我的 importedController.js 中,验证在我定义的 multer getFields() 函数之外不起作用(似乎合乎逻辑,因为请求尚未处理)。然而,如果我尝试将它包含在 multer 函数中:
importedController.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}
});
}
那么它总是returns一个错误,尽管字段输入是正确的。就好像验证是在 'non processed' 请求上执行的,其中 req.body 是空的。虽然代码现在可以工作所以不着急,但为了以后的项目,我想遵循新的语法。
非常感谢任何帮助!
编辑:感谢@gustavohenke 下面的回答,我找到了一个解决方案
意识到归根结底,我的问题与 multer 模块的工作方式有关,因为它似乎在处理表单数据(必须在验证之前)之前上传文件——至少是 multer模块似乎无法控制何时上传文件,使您无法在实际保存文件之前调用另一个中间件。
所以我最后做的是在客户端使用 ajax 首先只发送表单数据(保存文件以备后用),到与表单验证器链接的 multer().any()
中间件逻辑。根据第一次调用服务器给出的响应,然后我将它与另一个 ajax 链接起来,最终将文件上传到另一个路由,这次使用 multer(storage: myStorage).single('myFileInputName')
来上传文件。
仔细想想,这个解决方案似乎比我最初想的要好:它不仅避免了在表单输入错误的情况下保存文件,甚至还避免了使用任何带宽来发送文件(即可以很重)如果输入不正确。
当您说验证发生在 之前正文被 multer 处理时,您是正确的。
在这两种情况下,验证者都运行尽快;但请注意以下差异:
- 在您为遗留 API 提供的示例中,您在处理正文后在 multer 回调中定义验证 。因此,它有效。
- 但是,在您的检查 API 示例中,验证器是在 之前定义的 multer 有机会执行,所以您总是会出错 -
req.body
还是空的。
因此,我正在构建一个小应用程序以学习如何使用 express.js。我有一个非常简单的表单,同时提交一个文本字段和一个文件。这是通过 FormData 提交的,所以我在后端使用 multer 来处理请求。我想做的是对表单的文本输入执行验证 BEFORE 对文件采取任何行动(即仅在验证成功时保存,如果不发送某种错误消息) . 我以前就是这样做的
<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);
importedController.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
}
});
}
不过我注意到似乎有 a new syntax for express validator,所以我尝试遵循此语法并执行以下操作:
router.js
router.post('/upload', [ body('text-input', 'must be not empty').not().isEmpty()], importedController.processfunction);
但是在我的 importedController.js 中,验证在我定义的 multer getFields() 函数之外不起作用(似乎合乎逻辑,因为请求尚未处理)。然而,如果我尝试将它包含在 multer 函数中:
importedController.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}
});
}
那么它总是returns一个错误,尽管字段输入是正确的。就好像验证是在 'non processed' 请求上执行的,其中 req.body 是空的。虽然代码现在可以工作所以不着急,但为了以后的项目,我想遵循新的语法。 非常感谢任何帮助!
编辑:感谢@gustavohenke 下面的回答,我找到了一个解决方案
意识到归根结底,我的问题与 multer 模块的工作方式有关,因为它似乎在处理表单数据(必须在验证之前)之前上传文件——至少是 multer模块似乎无法控制何时上传文件,使您无法在实际保存文件之前调用另一个中间件。
所以我最后做的是在客户端使用 ajax 首先只发送表单数据(保存文件以备后用),到与表单验证器链接的 multer().any()
中间件逻辑。根据第一次调用服务器给出的响应,然后我将它与另一个 ajax 链接起来,最终将文件上传到另一个路由,这次使用 multer(storage: myStorage).single('myFileInputName')
来上传文件。
仔细想想,这个解决方案似乎比我最初想的要好:它不仅避免了在表单输入错误的情况下保存文件,甚至还避免了使用任何带宽来发送文件(即可以很重)如果输入不正确。
当您说验证发生在 之前正文被 multer 处理时,您是正确的。
在这两种情况下,验证者都运行尽快;但请注意以下差异:
- 在您为遗留 API 提供的示例中,您在处理正文后在 multer 回调中定义验证 。因此,它有效。
- 但是,在您的检查 API 示例中,验证器是在 之前定义的 multer 有机会执行,所以您总是会出错 -
req.body
还是空的。