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

我正尝试使用Multer包上传任何文件。 当我在我的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'文件夹中。

有没有办法达到这个目的?

先谢谢你。

更新

自从我发布原始答案以来,不less事情已经发生了变化。

multer 1.2.1

  1. 您需要使用DiskStorage来指定存储文件的位置方式
  2. 默认情况下,multer将使用操作系统的默认目录。 在我们的情况下,因为我们对位置特别。 我们需要确保该文件夹存在之前,我们可以保存在那里的文件。

注意:在提供目的地作为function时,您负责创build目录。

更多在这里

 '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用于创build目录, 以防万一它不存在

原始答案

你可以使用changeDest 。

重命名放置上传文件的目录的function。

它可以从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 }); 

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

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

要么

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

你可以像这样做一个function:

 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}); }); }); 

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

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

我想分享我的解决scheme(我使用express 4.13和multer 1.2):

import

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

存储variables (请参阅文档)

 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); 
 var storage = multer.diskStorage({ destination: function (req, file, cb) { if (req.path.match('/pdf')) { cb(null,<destination>) } }, filename: function (req, file, cb) { } }) 

这种情况下,path是唯一的。 您可以根据需要修改(检查终点{req.path})。 虽然这个解决scheme不是dynamic的。