multer:动态目标路径

时间:2017-01-02 15:23:00

标签: node.js multer

我正在编写节点应用程序,我正在寻找在服务器上上传文件的东西。当只有一个静态目录时,我可以上传文件。但是我需要为每个用户创建目录,然后根据登录的用户将文件上传到那些目录。我看起来很糟糕,但我尝试的所有内容都以错误结束:ENOENT:没有这样的文件或目录,打开...错误。我目前要做的是这个 -

let storage = multer.diskStorage({
  destination: function(req, file, cb) {
    let dest = path.join(__dirname, './documents', 'somenameigetfromtheuser');
    let stat = null;
    try {
      stat = fs.statSync(dest);
    }
    catch (err) {
      fs.mkdirSync(dest);
    }
    if (stat && !stat.isDirectory()) {
      throw new Error('Directory cannot be created');
    } 
    cb(null, dest);
  }
});

let upload = multer({
  storage: storage,
  dest: 'documents/'
});

app.post('/testUpload', upload.single('testfile'), (req, res) => {
  res.json({
    test: 'test'
  })
});

有一个similar question已被回答,但它对我来说不起作用,因为我想要请求对象中的目录名。

当我在multer初始化中删除存储属性时,文件以随机名称存储在documents目录中。我希望文件有其原始名称,我希望它存储在一个目录中,我从req对象获取目录的名称。
帮助一个兄弟,谢谢!

3 个答案:

答案 0 :(得分:0)

在我的项目中,我使用multer如下:

1.首先将文件存储在公共目录中,例如/ tmp /.

2.将文件复制/移动到您想要的任何位置,在我的情况下移动到CDN,并移动到您的用户文件夹中。

3.如果需要,在/ tmp中删除原始文件。

也许let upload = multer({ storage: storage, dest: 'documents/' });你应该删除dest,因为你在存储中指定了dest,对吗?

答案 1 :(得分:0)

<强>编辑

请参阅https://github.com/expressjs/multer#diskstorage

  

请注意,req.body可能尚未完全填充。这取决于客户端将字段和文件传输到服务器的顺序。

由于这个原因,首先在temp目录中写入文件,从req读取目录名称并移动文件:

fs = require('fs-extra'); //npm install fs.extra
...

var storage = multer.diskStorage({ 
    destination: function (req, file, cb) {
        cb(null, '../tempDir/')
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname)
    }
});

var upload = multer({ 
    storage: storage
}).single('file');

upload(req, res, function (err) {
    if (err) {
        res.json({});
        return;
    }

    var dir = JSON.parse(req.body.data).directory;
    var filename = req.file.filename;

    fs.move('../tempDir/' + fileName, '../tempDir/' + dir + '/' + fileName, function (err) {
        if (err) {
            return console.error(err);
        }

        res.json({});
    });

});

答案 2 :(得分:0)

确保首先添加客户端上的文本字段,然后再添加文件。就我而言,我有这样的东西:

` 

for(let i=0; i<files.length;i++)
{
  formData.append("files[]",files[i]);
}
formData.append("username",username);

  `

解决方法是先添加文本字段,如下所示:

`

formData.append("username",username);
for(let i=0; i<files.length;i++)
{
  formData.append("files[]",files[i]);
}

`