44

I'm just starting learning NodeJS and I am stuck with a problem. I would like to upload files to my server. To do so I searched and found out this module multer. Doing as the example on GitHub works:

var express = require('express');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });

var app = express()

app.post('/uploadImage', upload.single('image'), function(req, res) {
    console.log(req.file);
});

On posting an image with FormData to /uploadImage the image is saved in the uploads/ directory. The thing is the image is saved with a strange name and I would like to save it with its original name. To do so I understood that I would have to call app.use(multer({ dest: 'uploads/' }))' and then I would be able to access req.file in my function like:

app.post('/uploadImage', function(req, res) {
    console.log(req.file);
});

But I get an error on trying app.use():

TypeError: app.use() requires middleware functions
    at EventEmitter.use (project\node_modules\express\lib\application
.js:209:11)

Im using NodeJS 0.12.7 and Express 4.13.1

How can I achieve that upload? Thanks.

2
  • 1
    stackoverflow.com/a/31495796/4989460 Commented Jul 18, 2015 at 22:19
  • Oh my... I swer I have searched here... Thanks stdob... But well, strangely (for me) it stills uploads the file automatically that way... I though I would be able to control and write it with fs... Ill find a way, thx Commented Jul 18, 2015 at 22:28

7 Answers 7

62

You need to use app.use(multer({dest:'./uploads/'})) in the form of one of these:

app.use(multer({dest:'./uploads/'}).single(...));
app.use(multer({dest:'./uploads/'}).array(...));
app.use(multer({dest:'./uploads/'}).fields(...));

ie:

app.use(multer({dest:'./uploads/'}).single('photo'));

And be sure to have something like:

<form action="/postPhotos" enctype="multipart/form-data" method="post">
    <input type="file" name="photo">
    <input type="submit" value="Upload photo">
</form>

In your html.

Sign up to request clarification or add additional context in comments.

Comments

23
var app = require('express');

var multer = require('multer');

app=express();

app.use(multer({dest:__dirname+'/file/uploads/'}).any());

app.post('/upload',function(req,res){

    console.log(req.files);

    res.redirect('/');

});

2 Comments

This answer would be improved if it contained some explanation of how it answers the question and solves the problem.
StackOverflow requests that you post questions, comments, and answers in English only, please. (En inglés, por favor.) Also, use the edit link to update your answer directly.
12

The answer from @127.0.0.1 is correct, but in case you are using Express Router, the code changes a little bit:

var express = require('express');
var multer = require('multer');

var router = express.Router();

var uploads = multer({
  dest: 'public/uploads/'
});

router.post('/upload', uploads.single('avatar'), function(req, res, next) {
  console.log(req.file);

  //...
});

And the important bit, the form encoding should be enctype="multipart/form-data" as already said, like that:

<form action="/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="avatar">
    <input type="submit" value="Go avatar go!">
</form>

4 Comments

Hi, I'm using multer, expres, ng2-file-upload stack and with your exactly code doesn't works for me. The req.file is undefined and the info of my file is on req.files(on my html I dont have the multiple selector). When I click to upload on my button the server return file uploaded bt the file is not present on server. What would be doing wrong?
I would suggest testing it without angular first. I mean sending the request to the backend directly with Postman or CURL or your favorite tool. If that works, the problem is the frontend. If it doesn't, the problem is the backend. It is not going to solve the problem, but it will help you solve it faster.
If I add this app.use(multer({storage:storage}).single('file')); works fine but not as expected with callbacks. Could you check this question? stackoverflow.com/questions/44165037/…
Salvatorelab, I've been searching for 2 hrs+ trying to figure out why the I couldn't debug upload.single is not a function while use express router. Just want to point that out since that's not what the OP was trying to solve, might help someone else.
7

You can't change the file name using multer but you can use Node.js stream and fs module to copy the content of already uploaded file to new file(set as original file name) on same folder and delete old one.

First of all import fs, path and multer in your node script.

var express = require('express');
var multer = require('multer');
var fs = require('fs');
var pathModule = require('path');

Now, set destination directory of any type of files using multer as below.

var app = express();
app.use(multer({dest:__dirname+'/resoucres/'}).any());

Now use stream and fs to resolve your issue.

app.post('/uploadImage', function(request, response) {
    var readerStream = fs.createReadStream(request.files[0].path);
    var dest_file = pathModule.join(request.files[0].destination, request.files[0].originalname);
    var writerStream = fs.createWriteStream(dest_file);

    var stream = readerStream.pipe(writerStream);
    stream.on('finish', function(){
        fs.unlink(request.files[0].path);
    });
});

Comments

6

Since version 1.0.0

var upload = multer({ dest: 'tmp/' });
app.post('/file_upload', upload.single('photo'), function (req, res) {

1 Comment

what is upload.single('photo') here??
4

Changing to app.use(multer({dest:'./uploads/'}).single('photo')); in the app.js works for me to start the server

1 Comment

Can you explain a bit more?
2

I encountered the same problem. And I solved it. For the first problem, how to get the original file name? I printed the whole request and found we could get original name by using the path "req.file.originalname"

and the other question, how to use "app.use()"?
refers: here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.