如何使用multer在nodejs中设置不同的目的地?

时间:2014-09-06 07:56:51

标签: node.js multer

我正在尝试使用 Multer package 上传任何文件。当我在server.js文件中使用以下代码时,它工作正常。

var express = require('express'),
    app = express(),
    multer = require('multer');
app.configure(function () {
    app.use(multer({
        dest: './static/uploads/',
        rename: function (fieldname, filename) {
            return filename.replace(/\W+/g, '-').toLowerCase();
        }
    }));
    app.use(express.static(__dirname + '/static'));
});

app.post('/api/upload', function (req, res) {
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

var server = app.listen(3000, function () {
    console.log('listening on port %d', server.address().port);
});

我想要的是将文件存储在不同的位置。我曾尝试过代码,但它对我不起作用。

var express = require('express'),
    app = express(),
    multer = require('multer');
app.configure(function () {
    app.use(multer({
        //dest: './static/uploads/',
        rename: function (fieldname, filename) {
            return filename.replace(/\W+/g, '-').toLowerCase();
        }
    }));
    app.use(express.static(__dirname + '/static'));
});

app.post('/api/pdf', function (req, res) {
    app.use(multer({ dest: './static/pdf/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

app.post('/api/image', function (req, res) {
    app.use(multer({ dest: './static/image/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

app.post('/api/video', function (req, res) {
    app.use(multer({ dest: './static/video/'}));
    res.send({image: true, file: req.files.userFile.originalname, savedAs: req.files.userFile.name});
});

var server = app.listen(3000, function () {
    console.log('listening on port %d', server.address().port);
});

意思是,如果我点击http://localhost:3000/api/pdf文件应该存储在'pdf'文件夹中,如果我点击http://localhost:3000/api/video文件应该存储在'video'文件夹中。

有没有办法实现这个目标?

提前谢谢。

5 个答案:

答案 0 :(得分:11)

<强>更新

自从我发布原始答案以来,有很多事情发生了变化。

multer 1.2.1

  1. 您需要使用DiskStorage指定 where &amp; 如何存储的文件。
  2. 默认情况下,multer将使用操作系统的默认目录。在我们的例子中,因为我们特别关注这个位置。在我们将文件保存到那里之前,我们需要确保该文件夹存在。
  3.   

    注意:在将目的地作为函数提供时,您负责创建目录。

    更多here

    'use strict';
    
    let multer = require('multer');
    let fs = require('fs-extra');
    
    let upload = multer({
      storage: multer.diskStorage({
        destination: (req, file, callback) => {
          let type = req.params.type;
          let path = `./uploads/${type}`;
          fs.mkdirsSync(path);
          callback(null, path);
        },
        filename: (req, file, callback) => {
          //originalname is the uploaded file's name with extn
          callback(null, file.originalname);
        }
      })
    });
    
    app.post('/api/:type', upload.single('file'), (req, res) => {
      res.status(200).send();
    });
    

    fs-extra用于创建目录just in case if it doesn't exists

    原始回答

    您可以使用changeDest

      

    重命名放置上载文件的目录的功能。

    可从v0.1.8

    获取
    app.post('/api/:type', multer({
    dest: './uploads/',
    changeDest: function(dest, req, res) {
        var newDestination = dest + req.params.type;
        var stat = null;
        try {
            stat = fs.statSync(newDestination);
        } catch (err) {
            fs.mkdirSync(newDestination);
        }
        if (stat && !stat.isDirectory()) {
            throw new Error('Directory cannot be created because an inode of a different type exists at "' + dest + '"');
        }
        return newDestination
    }
    }), function(req, res) {
         //set your response
    });
    

答案 1 :(得分:8)

Multer是一个中间件,所以你可以这样传递它:

app.post('/test/route', multer({...options...}), module.someThing)

app.post('/test/route', multer({...options...}), function(req, res){
........some code ......
});

答案 2 :(得分:2)

您可以制作如下功能:

var uploadFnct = function(dest){
        var storage = multer.diskStorage({ //multers disk storage settings
            destination: function (req, file, cb) {
                cb(null, './public/img/'+dest+'/');
            },
            filename: function (req, file, cb) {
                var datetimestamp = Date.now();
                cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1]);
            }
        });

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

        return upload;
    };

然后在您的上传路线中使用它:

//Handle the library upload
    app.post('/app/library/upload', isAuthenticated, function (req, res) {
        var currUpload = uploadFnct('library');
        currUpload(req,res,function(err){
            if(err){
                 res.json({error_code:1,err_desc:err});
                 return;
            }
            res.json({error_code:0,err_desc:null, filename: req.file.filename});
        });
    });

答案 3 :(得分:0)

我尝试了这里显示的解决方案,但没有任何帮助。

ChangeDest attr不再可用(正如Sridhar在他的回答中提出的那样)

我想分享我的解决方案(我使用快递4.13和multer 1.2):

<强>进口

var express = require('express');
var router = express.Router();
var fs = require('fs');
var multer  = require('multer');


存储变量(请参阅文档here

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        var dest = 'uploads/' + req.params.type;
        var stat = null;
        try {
            stat = fs.statSync(dest);
        } catch (err) {
            fs.mkdirSync(dest);
        }
        if (stat && !stat.isDirectory()) {
            throw new Error('Directory cannot be created because an inode of a different type exists at "' + dest + '"');
        }       
        cb(null, dest);
    }
});


初始化Multer:

var upload = multer(
    { 
        dest: 'uploads/',
        storage: storage
    }
);


使用它!

router.use("/api/:type", upload.single("obj"));
router.post('/api/:type', controllers.upload_file);

答案 4 :(得分:0)

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    if (req.path.match('/pdf')) {
      cb(null,<destination>)
    }
  },
  filename: function (req, file, cb) {
  }
})

这适用于案例,路径是唯一的。您可以根据需要修改(检查终点{req.path})。虽然这个解决方案不是动态的。