首页 > 解决方案 > 使用 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 
  })

这对于创建每个字段都是强制性的已经足够了

但是对于编辑,如果用户不更新图像,我如何将数据保存到数据库,这意味着我只得到两个字段

  1. 姓名
  2. 地点

如果用户正在选择图像,那么我将保存,否则我将跳过图像并仅保存两个字段。我怎样才能做到这一点,如果用户没有选择正确的图像类型,那么我将不得不向用户显示错误。

这是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);
    }
  }
});

标签: node.jsexpressmulter

解决方案


首先:您应该在前端和后端都进行验证,以提供可能的最佳体验并避免“愚蠢”的错误,这些错误可能(并且将)最终成为等待 被任何获得它的人利用的缺陷。

第二:您永远不会向客户显示错误(永远)..考虑使用 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..
    
    };

推荐阅读