How to set different destinations in nodejs using multer?

I am trying to download any file using the Multer Package . It works fine when I use the following code in server.js file.

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

I want to store the file in different places. I tried the following code, but it does not work for me.

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

So, if I hit the file http://localhost:3000/api/pdf , it should be stored in the "pdf" folder, if I hit the file http://localhost:3000/api/video , it should be stored in the "video" folder .

Is there a way to achieve this?

Thanks in advance.

+6
source share
5 answers

Update

Several things have changed since I posted the original answer.

With multer 1.2.1 .

  • You need to use DiskStorage to indicate where and how the saved file is.
  • By default, multer will use the default directory for the operating system. In our case, as we are especially concerned with the location. We need to make sure that the folder exists before we can save the file there.

Note. You are responsible for creating the directory when you designate the destination as a function.

More 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 name with extn callback(null, file.originalname); } }) }); app.post('/api/:type', upload.single('file'), (req, res) => { res.status(200).send(); }); 

fs-extra to create a directory in case it does not exist

Original answer

You can use changeDest .

Function for renaming a directory to host downloaded files.

It is available from 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 }); 
+9
source

Multer is a middleware, so you can pass it like this:

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

or

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

You can make a function like this:

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

And then use it in your download route:

 //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}); }); }); 
+1
source

I tried the solutions shown here, but nothing helped me.

ChangeDest attr is no longer available (as Sridhar suggests in his answer)

I want to share my solution (I use express 4.13 and multer 1.2):

Import

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


Storage variable (see documentation 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 Initialization:

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


Using it!

 router.use("/api/:type", upload.single("obj")); router.post('/api/:type', controllers.upload_file); 
0
source
 var storage = multer.diskStorage({ destination: function (req, file, cb) { if (req.path.match('/pdf')) { cb(null,<destination>) } }, filename: function (req, file, cb) { } }) 

This works in case the path is unique. You can change (check endpoint {req.path}) according to your needs. Although this solution is not dynamic.

0
source

Source: https://habr.com/ru/post/974912/


All Articles