File uploads using Node.js

File upload in node.js seems tedious due to its async nature and network programming approach. However, it is one of the easiest file upload mechanism I have seen yet.

Prerequisites: You should know how to handle router in Express.

LIVE DEMO DOWNLOAD

How to perform file upload?

I am going to use express framework and middleware called “multer”. This middleware is designed for handling the multipart/form-data.

In front-end script, we will set the “target” parameter of FORM to our router. for.eg  /upload/picture and in app.get(‘/upload/picture’, …) we will be able to handle our file. Let’s see how.

If you are new to Node and Express then you won’t regret taking our Node course. Its FREE!

Our project:

This project is simple. We will have a simple express web server which does the task of routing and other stuff. Multer will take care of the file handling and HTML for handling form input.

change log
#1: Fixing global variable issue.
#2: Upgrading to multer v 1.1.0.
package.json
{
  "name": "file_upload",
  "version": "0.0.1",
  "dependencies": {
    "express": "4.13.3",
    "multer": "1.1.0"
  },
  "devDependencies": {
    "should": "~7.1.0",
    "mocha": "~2.3.3",
    "supertest": "~1.1.0"
  }
}

Installing dependency:

Save the package.json in folder and type

npm install

to install the required stuff.

This code is updated with the latest version of Multer.

Server.js
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, file.fieldname + '-' + Date.now());
  }
});
var upload = multer({ storage : storage}).single('userPhoto');

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

app.post('/api/photo',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("Working on port 3000");
});
index.html
<form id        =  "uploadForm"
     enctype   =  "multipart/form-data"
     action    =  "/api/photo"
     method    =  "post"
>
<input type="file" name="userPhoto" />
<input type="submit" value="Upload Image" name="submit">
</form>

Running project:

Copy code and save them in folder. Type

node Server.js

to run the project. Visit localhost:3000 to view the app. Select the file and check the uploads folder. Your file must be present there!

Explanation :

In our Server.js file, we have configured multer. We have made custom middle-ware function to choose the storage engine which is Disk because we want files to store in disk and appending the file name with current date just to keep the uniqueness of files.

After completing upload , req.files variable holds following array of information.

{
  userPhoto:
  {
     fieldname: 'userPhoto',
     originalname: 'banner.png',
     name: 'banner1415699779303.png',
     encoding: '7bit',
     mimetype: 'image/png',
     path: 'uploads&#92;banner1415699779303.png',
     extension: 'png',
     size: 11800,
     truncated: false,
     buffer: null
 }
}

We are initializing the multer in our /api/photo/ router and in callback we are receiving the error. If there is no error that means file is uploaded.

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

In HTML form you must mention enctype=”multipart/form-data” else multer will not work.

Performing file validation:

To perform validation on Server end, multer provides limits array parameter which have following parameters. ( Reference: Github official page. )

  • fieldNameSize – integer – Max field name size (Default: 100 bytes)
  • fieldSize – integer – Max field value size (Default: 1MB)
  • fields – integer – Max number of non-file fields (Default: Infinity)
  • fileSize – integer – For multipart forms, the max file size (in bytes) (Default: Infinity)
  • files – integer – For multipart forms, the max number of file fields (Default: Infinity)
  • parts – integer – For multipart forms, the max number of parts (fields + files) (Default: Infinity)
  • headerPairs – integer – For multipart forms, the max number of header key=>value pairs to parse Default: 2000 (same as node’s http).

You can define it like this

limits: {
  fieldNameSize: 100,
  files: 2,
  fields: 5
}

In our code.

var upload = multer({ storage : storage},{limits : {fieldNameSize : 10}}).single('userPhoto');

Conclusion:

Multer is very nice middleware created by Express community. It really helps us to quickly develop critical code like File uploads in Node.js easily. I hope you find this tutorial helpful.

Further reading: