一、需求

express 使用 multer 实现文件上传的时候,需要过滤文件后缀,并且对报错信息进行控制。

multer 的基本使用:

之前上传文件的时候,没有做文件上传后缀的过滤,也没做异常处理。

这里的异常不是简单的抛出异常这么简单,需要自定义返回错误信息,比如返回 json 数据。

二、实现

2、文件后缀检查方法 checkFileExt

这个规则可以修改成不同的规则方法,allow 或者 deny 表示是允许还是拒绝。

rule 的验证我用的很简单的,就是 includes

/**
 * @name checkFileExt
 * @description 检查文件后缀是否满足要求
 * @param {Boolean} allow  // 描述规则是 allow 还是 deny
 * @param {String} rule // 规则字符串
 * @param {String} ext  // 文件后缀名
 */
function checkFileExt(ext,allow=true,rule='png|jpeg|bmp|svg|jpg'){
  if(!ext) return false;
  if(allow) return rule.includes(ext);
  return !rule.includes(ext);
}

2、文件过滤 fileFilter

这个方法调用了 checkFileExt,需要注意的是,如果下面两个 cb 的调用分别表示通过和拒绝文件上传:

  • cb(null,true) :允许上传
  • cb(null,false):不允许上传 (后面同时抛出异常)
/**
 * @name fileFilter
 * @description 文件过滤方法
 * @param {*} req 
 * @param {*} file 
 * @param {*} cb 
 */
function fileFilter(req,file,cb){
  let ext = file.originalname.split('.');
  ext = ext[ext.length-1];
  // 检查文件后缀是否符合规则
  if(checkFileExt(ext,true)){
    cb(null,true);
  }else{
    // 不符合规则,拒绝文件并且直接抛出错误
    cb(null,false);
    cb(new Error('文件类型错误'));
  }
}

3、文件上传使用手动调用中间件方式

为了自己调用中间件,使用的方式和之前不太一样:

const baseUpload = multer({storage,fileFilter});
const upload = baseUpload.single('file');
/**
 * @name uploadMiddleware
 * @description 文件上传中间件,upload 方法调用的时候 会有 err 进行错误判断
 * @param {*} req 
 * @param {*} res 
 * @param {*} next 
 */
function uploadMiddleware(req,res,next){
  upload(req,res,(err)=>{
    if(err){
      // 进行错误捕获
      res.json({code:-1,msg:err.toString()});
    }else{
      next();
    }
  });
}
app.post('/',uploadMiddleware,(req,res)=>{
  let savePath = req.file.path.replace(/\\/g,'/').replace(fileBasePath,'');
  res.send(savePath);
});

三、完整示例

自定义异常捕获和文件后缀过滤,我整合了一个完整的代码:

四、效果:

文件上传之后的文件夹:

4.jpg

文件上传之后,获取到了的需要的文件路径:

3.jpg