node.js - 使用 Multer 进行文件验证 - Expressjs
问题描述
我有一个包含多个字段的表单,其中一个是用于上传图像的文件字段。
name = 'john doe'
location = 'Some location'
image = (binary)
我的问题是我如何验证这个图像文件的时间,即创建和更新。
对于创建,每个字段都是必需的,但对于编辑,用户可能不想更新图像,而只想更新文本字段,因此他不会选择图像文件
router.post('/user', upload.single('image'), userRoute);
我已经制作了这样的中间件,但这并没有给出正确的验证结果。假设用户选择了一张图片并按下了提交按钮,那么我将在 req.file 中得到类似的内容。
{ fieldname: 'image',
originalname: 'images (2).jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'uploads/top-level',
filename: 'images (2)-1583345397445.jpg',
path: 'uploads\\top-level\\images (2)-1583345397445.jpg',
size: 33766 }
这是有道理的,但假设用户选择了一些不是我希望用户提交的文件类型的 zip 文件,因此我必须抓住它并向用户展示文件类型不是图像。让我知道我是否可以使用上述中间件。
router.post('/user', userRoute);
我的 userRoute 函数我写了这样的东西来捕捉错误
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// catch error and show to user
} else if (err) {
// catch error and show to user here also
}
// Logic goes here
// and we get the req.body here
})
这对于创建每个字段都是强制性的已经足够了
但是对于编辑,如果用户不更新图像,我如何将数据保存到数据库,这意味着我只得到两个字段
- 姓名
- 地点
如果用户正在选择图像,那么我将保存,否则我将跳过图像并仅保存两个字段。我怎样才能做到这一点,如果用户没有选择正确的图像类型,那么我将不得不向用户显示错误。
这是multer代码
var upload = multer({
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/top-level')
},
filename: function (req, file, cb) {
cb(null, file.originalname.split('.')[0] + '-' + Date.now() + path.extname(file.originalname))
}
}),
fileFilter: (req, file, cb) => {
if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
cb(null, true);
} else {
return cb(null, false);
}
}
});
解决方案
首先:您应该在前端和后端都进行验证,以提供可能的最佳体验并避免“愚蠢”的错误,这些错误可能(并且将)最终成为等待 被任何获得它的人利用的缺陷。
第二:您永远不会向客户显示错误(永远)..考虑使用 connect-flash 中间件在通知中或应用程序的任何位置发送 flash 消息(检查 flash() 的文档)。
在前端,您应该阻止通过扩展名上传文件类型,这在本机 html 或通过 JS 上都很容易(您没有指定前端,所以为了清楚起见,我将跳过这部分)。
在后端,您可以检查“req.file.mimetype”以查看它是否在您的上传功能允许的扩展数组中。像这样的东西:
var authorizedMimeTypes=['jpg','jpeg',...];
if(req.file.mimetype in authorizedMimeTypes){
//your code goes here..
}else{
//your error code goes here..
};
推荐阅读
- python - Numpy 矩阵逆似乎使用多个线程
- node.js - 使用 Vault 存储客户端 PEM 和 KEY 以供以后与 fetch 一起使用
- c# - 剃刀组件的 HtmlTargetElementAttribute 等效项?
- c++ - 如何修复:自定义 QGraphicsItem 接收 mousePressEvent 坐标延迟/滞后?
- mql5 - 盈亏平衡功能中的无效止损
- matlab - 在Matlab中使用for循环将矩阵划分为列数相等的小矩阵?
- go - 如何使用 gorm 解决“运行时错误:无效的内存地址或 nil 指针取消引用”
- python - 在 Python 中创建赛车,为什么我的车没有赛车?
- java - Java - Base64 解码
- r - 在 r 中绘制两个 sf POINT 特征之间的线