Comments (40)
Hi! I tried the solutions shown here but nothing helped me. I am developing a little server using express and my "boss" asked an uploads folder with users sub-folders and inside this folders, its uploaded files.
I want to share my solution (I am using express 4.13 and multer 1.2):
Imports:
var express = require('express');
var router = express.Router();
var fs = require('fs');
var multer = require('multer');
Storage variable (see documentation)
var storage = multer.diskStorage({
destination: function (req, file, cb) {
var newDestination = 'uploads/' + req.user._username;
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 + '"');
}
cb(null, newDestination);
}
});
Initializing Multer:
var upload = multer(
{
dest: 'uploads/',
limits: {
fieldNameSize: 100,
fileSize: 60000000
},
storage: storage
}
);
Using it!
router.use("/upload", isAuthenticated);
router.use("/upload", upload.single("obj"));
router.post('/upload', controllers.upload_file);
from multer.
It is available if the multer instance is placed on the post or put route. I have a doc and examples explaining how to do this.
from multer.
Getting an error when trying to use changeDest:
Error: ENOENT, open 'my path'
my code:
var express = require('express');
var multer = require('multer');
var router = module.exports = express.Router();
router.use(multer({
dest: './uploads',
changeDest: function(dest, req, res){
dest += '/haha';
return dest;
},
onFileUploadStart: function(file){
console.log('starting');
}
}));
router.post('/upload', sendResponse);
function sendResponse(req, res){
res.send('ok');
};
EDIT:
I am an idiot.
adding code for creating the destination folder made it work:
try{
stat = fs.statSync(dest);
}catch(err){
fs.mkdirSync(dest);
}
from multer.
dest: 'uploads/', insteed can i possible to specify https://www.abcabc.in/assets/doc/journal/
from multer.
Currently the option is not available. You will need to move the files
to the desired location after the upload is complete.
Akshay wrote:
I'm not getting how to set different destination path for say
different routes?—
Reply to this email directly or view it on GitHub
#58.
from multer.
It might be unrelated, but when I send a mutlipart/form file from a client, I append a "fullPath" string containing the original path of the file, not just the file name. It seems like when the data gets to multer, this information cannot be accessed, and is then lost when we get back the File object. Is there a way to access custom data appended to the multipart form?
from multer.
Are you appending the full path as a value of an html input element of type "text" or "hidden"? If yes, then that element should show up after multer runs in req.body.[yourAppendedInputElementName]. Or are you letting the browser pass the original path as part of the "file" input element? If I recall, some browsers support this but others don't.
from multer.
the latter, as this info pertains to a single file, not the entire form (as the form might contain several files). I could rewrite the upload process so as to have one file per form, but would rather find a server side way to handle this. I know all browsers don't support it though, it's just not an issue for my application
from multer.
Is it posible to do it with the rename() option?
from multer.
I guess this conversation got a little unrelated. It's good that @JesusMurF's comment refers back to the initial post in this thread about "Setting different destination paths".
No, do not use rename() to set the destination path. rename() returns a file name and appends it to the destination directory. Here is the code from the source:
newFilename = rename(fieldname, filename.replace(ext, '')) + ext;
newFilePath = path.join(dest, newFilename);
Also when using options.dest, multer will verify the destination directory has been created and, if it hasn't, will create the directory (defaulting to the system's "temp" directory).
from multer.
I'd like to close this issue, but I think this question will come up more often. We should update the docs with an example before closing. The solution is to put separate instances of multer middleware on the actual route. This code would allow for different dest paths to be specified:
var multer = require('multer');
var mwMulter1 = multer({ dest: './uploads1/' });
app.post('/files1', mwMulter1, function(req, res) {
// check req.files for your files
});
var mwMulter2 = multer({ dest: './uploads2/' });
app.post('/files2', mwMulter2, function(req, res) {
// check req.files for your files
});
from multer.
Please go ahead.
from multer.
And if the name of the path is the user id ?
If you need to dynamically set the name, it does not solve the question.
Is there any way to handle the destination of the uploaded file in callback function (req,res) ?
Regards,
from multer.
i have the same problem with leo-one.
from multer.
To be honest it lack of several features.
I wish my folder to be "/upload/" + user.id, but it seems to be a challenge to get it.
Should I define hundreds of destinations for each user?
from multer.
@Torone @Leo-One @NullArgument You could solve it by moving the file after it got saved. I'm using the default destination and treating it as a temporary location. Then moving the file in the post route. (Not very elegant, but it works.)
from multer.
@sigurdga Yes it is the only working solution I found yet. But as you said, not elegant. I hope to have in future something I can customise entirely as I did with previous versions of Express. Thanks
from multer.
@sigurdga Do you know also how to handle multiple files upload? Because it do not convert itself to array as well...
Selecting more files it save just one.
Thanks
from multer.
@Torone I don't know what gets wrong in your case, but I guess it is how you put together your form. I have put together a (minimal) example showing how I'm doing file uploads, using Express and Multer with or without Dropzone: https://github.com/sigurdga/express-multer-dropzone-example/
from multer.
@sigurdga yeah, but moving the file isn't good for system's resources, what about big files? what if i allow users to upload files up to 10GB? Moving big files again and again isn't a very good idea.
from multer.
I agree with @NullArgument .
I should be able to decide where to put my file, most of the time the repository of the file is based on user credentials (id, nickname, whatever).
from multer.
thanks guys, i think moving files is not a bad idea for security or buffer reasons. I'll give it a shot. Interesting.
from multer.
@windmaomao "i think moving files is not a bad idea" Yeah, keeping the server busy for something big (10GB or more) that you will reject in the end is really cool.
from multer.
@NullArgument well, it might not work for you, but how many system will have 10GB files in daily basis ? Aiming for 1% of requirement is something i don't want to be a developer :) Or maybe i just don't want to be developer. Since sometimes we're missing a lot of fun things.
from multer.
I'm catching up on outstanding issues.... Since my original post, you guys have made compelling reasons why the developer should have more control over the upload directory. (Thanks!) I've added an option in my local tests for it. I'll push as soon as I can test it.
from multer.
thanks JP, appreciate your time. We're more looking for controlling the upload folder dynamically, ex. case by case depending on the file or req info. Or maybe just a pretty entry saying here is the file that is uploaded, do whatever you want with it. Either way will work.
from multer.
The renameDestDir
has now been added. Please see Multer's README for more info about it. Let me know if this works for you and then we can close this issue.
from multer.
well done
from multer.
this is better than i expected, thanks JP, btw, can we do file instead of dest in the renameDestDir parameters ? is this possible ? if it's too much trouble, then don't worry about it. Basically after the upload, we'd like to know all information of the file before we can make decisions on the folder name or structure.
from multer.
When renameDestDir runs, the file object hasn't been created yet. Maybe a separate function would be better in which the file object is passed in for evaluation and then returned. Only then would its pathing would be created and it would continue to proceed.
A work around that might fit your situation: if you need to know all info about the file before making decisions on dir/folder, you could use inMemory: true
and then write out the file yourself. The only issue is that keeping the file inMemory is (a) slower and (b) could have you run out of RAM at some point.
from multer.
you are right JP, thanks for explaining that to me, now I see.
ok, if i really need some basic information, i can just look at file object inside req. that should do it for now. Asking a file object might be a wrong approach here anyway, sorry about the trouble, i think whatever you said makes sense.
from multer.
Ok, I reread your question.... Yes, after the upload, req.files
contains all the file objects. No changes are needed to access this list.
from multer.
FYI: In the source, we've renamed renameDestDir
to changeDest
, so when 0.1.8 is published to npm, you'll want to use changeDest
.
from multer.
Perfect. changeDest
works great! Thank you very much!
from multer.
Cool.
from multer.
Is the changeDest still a parameter, couldn't find anything about it in the readme or searching through the code base..
Also, If it is available wouldn't it be bad to use fs.statSync, since its synchronous?
wouldn't it be better to use fs.stat with a promise?
sorry new and trying to utilize best practices
from multer.
@JordyCuan do you happen to know why i cant access the req.body params inside the destination function? Or how i should go about actually accessing it?
Edit: nvm:
"Note that req.body might not have been fully populated yet. It depends on the order that the client transmits fields and files to the server."
from multer.
@bote795 did you manage to access req.body
params? I am not able to figure it out, even I tried changing the order that the client transmits fields.
Client:
let data = new FormData()
data.append('folder', 'product')
data.append('file', event.target.files[0])
from multer.
This is my code:
const storage = multer.diskStorage({
destination: function(req, file, callback){
callback(null, path.dirname('D:/') + 'Integra Qamba Site/');
},
filename: function(req, file, callback){
let data = new Date();
callback(null, dateTime +".jpg");
}
});
Hope this help!
from multer.
Hola, lo que funciono para mi fue:
Desde el frontEnd envía tu archivo binario al final del formData asi multer lo ultimo que procesara sera el binario.
from multer.
Related Issues (20)
- ERROR UPLOADING FILE using the javascript and I also use multer in handling the fileupload HOT 5
- Translation of Documentation to Indonesian
- Multer gives error on serverless if using without express js
- Error in uploading a photo in javascript using a multer. HOT 2
- There is a way to effectively add a custom Error handler to multer? HOT 2
- (love) Just to tell you how great your software is HOT 1
- TypeError: Cannot read properties of undefined (reading 'length') when fieldNameSize is not set HOT 6
- Upgrade to the latest version of busboy to prevent potential DOS attack via Dicer HOT 1
- File upload got stuck while uploading large text files HOT 3
- Upload file use Multer with Multer-gridfs-storage in environment of bun is not working but when I use environment of nodejs then it's working? HOT 1
- req.file returning Undefined on frontend, but with Insomnia returns correctly HOT 4
- Custom storage engine not working
- MulterError: Unexpected field when trying to use different storage configuration HOT 1
- Update Docs: Error: read ECONNRESET thrown during test using supertest, mocha but works fine while using postman. HOT 1
- Why does Multer does not release memory? HOT 1
- `preservePath` option not respected HOT 2
- This module only works with node 14 or LOWER HOT 39
- file.size undefined with multiple files HOT 2
- Request not finish when recieve an error HOT 11
- File upload middleware does not work when I chain it with other middlewares. I get req.file = undefined HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from multer.