Giter Site home page Giter Site logo

Comments (40)

JordyCuan avatar JordyCuan commented on April 26, 2024 10

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.

jpfluger avatar jpfluger commented on April 26, 2024 2

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.

tkolsen avatar tkolsen commented on April 26, 2024 2

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.

Mutharaju avatar Mutharaju commented on April 26, 2024 1

dest: 'uploads/', insteed can i possible to specify https://www.abcabc.in/assets/doc/journal/

from multer.

hacksparrow avatar hacksparrow commented on April 26, 2024

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.

gyril avatar gyril commented on April 26, 2024

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.

jpfluger avatar jpfluger commented on April 26, 2024

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.

gyril avatar gyril commented on April 26, 2024

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.

JesusMurF avatar JesusMurF commented on April 26, 2024

Is it posible to do it with the rename() option?

from multer.

jpfluger avatar jpfluger commented on April 26, 2024

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.

jpfluger avatar jpfluger commented on April 26, 2024

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.

hacksparrow avatar hacksparrow commented on April 26, 2024

Please go ahead.

from multer.

leonardojobim avatar leonardojobim commented on April 26, 2024

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.

wirespecter avatar wirespecter commented on April 26, 2024

i have the same problem with leo-one.

from multer.

Torone avatar Torone commented on April 26, 2024

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.

sigurdga avatar sigurdga commented on April 26, 2024

@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.

Torone avatar Torone commented on April 26, 2024

@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.

Torone avatar Torone commented on April 26, 2024

@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.

sigurdga avatar sigurdga commented on April 26, 2024

@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.

wirespecter avatar wirespecter commented on April 26, 2024

@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.

Torone avatar Torone commented on April 26, 2024

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.

windmaomao avatar windmaomao commented on April 26, 2024

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.

wirespecter avatar wirespecter commented on April 26, 2024

@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.

windmaomao avatar windmaomao commented on April 26, 2024

@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.

jpfluger avatar jpfluger commented on April 26, 2024

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.

windmaomao avatar windmaomao commented on April 26, 2024

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.

jpfluger avatar jpfluger commented on April 26, 2024

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.

Torone avatar Torone commented on April 26, 2024

well done

from multer.

windmaomao avatar windmaomao commented on April 26, 2024

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.

jpfluger avatar jpfluger commented on April 26, 2024

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.

windmaomao avatar windmaomao commented on April 26, 2024

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.

jpfluger avatar jpfluger commented on April 26, 2024

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.

jpfluger avatar jpfluger commented on April 26, 2024

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.

eduardocasas avatar eduardocasas commented on April 26, 2024

Perfect. changeDest works great! Thank you very much!

from multer.

jpfluger avatar jpfluger commented on April 26, 2024

Cool.

from multer.

bote795 avatar bote795 commented on April 26, 2024

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.

bote795 avatar bote795 commented on April 26, 2024

@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.

atulmy avatar atulmy commented on April 26, 2024

@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.

comfreis avatar comfreis commented on April 26, 2024

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.

Roberto-LRivas avatar Roberto-LRivas commented on April 26, 2024

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.

Mi FrontEnd:
image

Mi backeEnd:
image

from multer.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.