multer是expressjs中上传文件使用的中间件,配置简单,使用也简单,非常方便,但是使用过程中却又不少的坑。

multer使用的案例

multer使用简单,假设你已经npm安装了multer,使用方法如下:

var multer = require('multer');
var storage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, './public/uploads');
  },
  filename: function(req, file, cb) {
    var fileFormat = (file.originalname).split(".");
    cb(null, file.fieldname + '-' + Date.now() + "." + fileFormat[fileFormat.length -1]);
  }
});
var upload = multer({ 
  storage: storage,
  fileFilter: function(req, file, cb) {
    if (file.mimetype !== 'image/png' && file.mimetype !== 'image/jpg' && file.mimetype !== 'image/jpeg'){
      cb(null, false);
    }
    else{
      cb(null,true);
    }
  }
});
app.post('/upload', upload.single('img'),  MovieController.upload);

案例中,destination配置项就是设置储存的地方,filename配置项是命名储存的文件名包括后缀名。
filefilter配置参数是过滤指定的文件类型或者放行指定的文件类型。最后在路由中添加中间件使用multer,multer会自动处理form-data。

multer坑一

使用multer的时候,可以添加进路由中以中间件使用,一种是upload.single('img'),一种是upload.array('imgs',8),顾名思义一个是上传单个文件,一个是上传复数的文件。但是这里有个坑,就是其中的参数"img",必须和前端传输来的filed一致,也就是表单中的input的name必须和这里的参数名一致,要不然就会引起Internal Server Error500错误。这个地方在文档中其实也没有很好的标注出来。

multer坑二

在配置storage的时候,其实multer有多种储存方式,一种是内存储存,我这里使用的是硬盘储存的方式,有一次想在storage配置中使用动态储存路径,因为其作为中间件使用,所以也会接受req参数,我的设想是在storage配置中获取req中的表单body数据,并且使用此body数据动态设置destination储存路径,但是调试来调试去,在storage中req都获取不到body的数据,一直认为是前端的问题,前前后后折腾了几个小时,最后才发现upload中间价只会处理post上传的文件,并不会解析其中的表单中的数据,所以最后的解决方案是在controller中获取file信息,再使用fs移动和修改文件。