New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set different destination path #58
Comments
Currently the option is not available. You will need to move the files Akshay wrote:
|
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. |
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? |
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. |
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 |
Is it posible to do it with the rename() option? |
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). |
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
}); |
Please go ahead. |
And if the name of the path is the user id ? Regards, |
i have the same problem with leo-one. |
To be honest it lack of several features. |
@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.) |
@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 |
@sigurdga Do you know also how to handle multiple files upload? Because it do not convert itself to array as well... |
@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/ |
@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. |
I agree with @NullArgument . |
thanks guys, i think moving files is not a bad idea for security or buffer reasons. I'll give it a shot. Interesting. |
@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. |
@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. |
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. |
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. |
The |
well done |
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. |
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 |
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. |
Ok, I reread your question.... Yes, after the upload, |
FYI: In the source, we've renamed |
Perfect. |
Getting an error when trying to use changeDest: 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: try{
stat = fs.statSync(dest);
}catch(err){
fs.mkdirSync(dest);
} |
Cool. |
Is the changeDest still a parameter, couldn't find anything about it in the readme or searching through the code base.. |
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); |
@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: |
@bote795 did you manage to access Client:
|
dest: 'uploads/', insteed can i possible to specify https://www.abcabc.in/assets/doc/journal/ |
This is my code: const storage = multer.diskStorage({ Hope this help! |
I'm not getting how to set different destination path for say different routes?
Example : app.post('/api/upload', function (req, res) { // here i want destination as dest: './static/uploads/'
and app.post('/api/pic', function (req, res) { // here i want destination as dest: './static/pic/
and app.post('/api/pdf', function (req, res) { // here i want destination as dest: './static/pdf/'
The text was updated successfully, but these errors were encountered: