multer模块diskstorage方式注意事项

------------------8.15更新------------------

关于req.body为空的问题,之前在multer的github上开了个issue提了这个问题,multer的作者回复我说目前没有直接的solution,但推荐一个workaround:

...    
formData.append('uid',uid);
formData.append('avatar',avatarFile);

在前端js控制数据装载的顺序,只要保证数据装载在file文件之前即可,亲测有效。

-----------------------------------------

以前用的时候都没留意。。。

multer 虽然给出了一个自定义存储的方式,让开发者设定存储路径和命名:

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, '/tmp/my-uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now())
  }
})

var upload = multer({ storage: storage })

这里有两点值得留意:

1是destination和filename函数的参数req,在这里req.body是空对象{},未装载formdata的文本域数据。

//想直接根据req.body的参数动态创建文件夹存储文件是不行的!!
  destination: function (req, file, cb) {
    console.log('this is file')    
    console.log(file)
    let avatarPath = path.join(__dirname,`../../asserts/${req.body.uid}/avatar`);
    if (!fs.existsSync(avatarPath)) {
            fs.mkdirSync(avatarPath);
    }
    cb(null, avatarPath)
  },
...

类似上面直接根据req.body.xxx动态创建文件夹就不行了。

2是file虽然装载了文件对象,但是信息不全,下面两张图分别是multer.diskstorage回调和后续中间件函数中file的信息:

当我们想根据请求中的数据动态创建文件夹保存文件的时候,由于diskstorage方式必须先确定保存路径、req.body中未存储任何信息、且其file参数只装载极有限的信息,显然是不行的。

multer插件提供了另一种方式MemoryStorage,在upload.single('avatar')之后将文件转为buffer保存在req.file.buffer中,这时候我们就可以在获取req.body.xxx后,通过fs创建文件夹,并通过fs.writeFile(path,new Buffer(req.file.buffer),callback)的方式实现了。

//Demo
var storageAvatar = multer.memoryStorage()
var uploadAvatar = multer({ storage: storageAvatar })

exports.avatarMiddleWare= uploadAvatar.single('avatar');
exports.avatar=function(req,res){
  let uid = req.body.uid,filetype;
  let mime = req.file.mimetype.split('/');
  if(mime[0] === 'image') filetype = `.${mime[1]}`;
  ...

 fs.writeFile(path.join(__dirname,`../../asserts/userData/${uid}/avatar/avatar-${t imeStamp}${filetype}`), 
     new Buffer(req.file.buffer), 
     function(err) {
        if(err) {console.log(err)}
    });

  UserModel.findOneAndUpdate(
  ...

猜你喜欢

转载自blog.csdn.net/weixin_36094484/article/details/81415060