NodeJs : Uploading files with Express & Multer

Uploading files to server is one of the mostly used features in modern web applications. If you are using node.js "busboy" was the best solution for sometime. But it is somewhat complicated as you can see from examples in it's GitHub homepage.

Multer is the latest best solution for this problem. it is a node.js middle-ware for handling multipart/form-data, which is primarily used for uploading files. It is written on top of busboy for maximum efficiency.

Here is an example of how to use Multer to upload files.


  1. Require relevant node packages.
    
    var express =   require("express");
    var multer  =   require('multer');
    var app         =   express();
    

  2. Decide Destination and saved name of the uploaded file using disk storage engine of multer.
    
    var storage =   multer.diskStorage({
      destination: function (req, file, callback) {
        callback(null, './uploads');
      },
      filename: function (req, file, callback) {
        callback(null,Date.now()+file.originalname);
      }
    });
    

    here destination is "uploads" folder in root directory.You can change it as you want in destination function. file name to be saved can be specify in the function "filename".

  3. Create a upload function with Multer.
    
    var upload = multer({ storage : storage}).single('upload_file');
    

    This takes previously created storage object as an arguement

  4. Handle route to home page.
    
    app.get('/',function(req,res){
          res.sendFile(__dirname + "/upload.html");
    });
    

    "upload.html" HTML page will be sent when user accessing the home page. Code for that HTML page is given bellow in the post

  5. Handle route to upload page.
    
    app.post('/upload',function(req,res){
        upload(req,res,function(err) {
            if(err) {
                return res.end("Error uploading file.");
            }
            res.end("File is uploaded");
        });    
    });
    
    

    Html form directing user to "/upload" URL and previously created upload method will be used to upload the file

  6. Assigning a port to the server.
    
    app.listen(3000,function(){
        console.log("listening on port 3000");
    });
    

    Finally server will be listened on port 3000 when it is run
  7. If you want to preform validation it can be done with a limit object for Multer as specified in it's GitHub page.
    
    limits: {
      fieldNameSize: 100,
      files: 2,
      fields: 5
    }
    
    var upload = multer({ storage : storage},{limits : {fieldNameSize : 10}}).single('upload_file');
    
    
Complete code for the server

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

var storage =   multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, './uploads');
  },
  filename: function (req, file, callback) {
    callback(null,Date.now()+file.originalname);
  }
});

var upload = multer({ storage : storage}).single('upload_file');

app.get('/',function(req,res){
      res.sendFile(__dirname + "/upload.html");
});

app.post('/upload',function(req,res){
    upload(req,res,function(err) {
        if(err) {
            return res.end("Error uploading file.");
        }
        res.end("File is uploaded");
    });    
});

app.listen(3000,function(){
    console.log("listening on port 3000");
});


Here is the HTML for upload.html file

<!DOCTYPE html>
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file : <br />
<form id ="uploadForm" enctype ="multipart/form-data" action="/upload" method = "post">
<input type="file" name="upload_file" />
<input type="submit" value="Upload" name="submit">
</form>
</body>
</html>


3 comments:

  1. This code works fine! But I have a doubt. How can I stay in the upload.html page after the upload? Because, just upload finish, I am redirect to '/upload'. I don't want that. I want to upload and stay in original path.

    ReplyDelete
    Replies
    1. Sorry for late reply.,
      You can do that in post method of the server using ,
      res.sendFile(__dirname + "/upload.html");

      Delete
  2. Hello there :)
    It is a way for uploading multiple files... I keep searching !
    Thanks

    ReplyDelete