Build simple file upload system using Node.js

File upload is a very common feature on a website but there is only few resources teaching you how to do it using the Node.js.

Preparation

I found a very useful and easy-to-use module called Multer. It can help you handle multipart/form-data, which is used to transfer files. Because it is a Node.js module, the installation is very easy, just use npm install multer command in your command line. Here I’m gonna show you how to create an endpoint to handle file upload so I’ll use Express.js as well.

Usage

You can find the documentation on their GitHub page but I’ll demo how to build a simple api to handle file upload.

First, require the module.

var multer = require('multer');

And then you can simply create an endpoint like this.

var upload = multer({storage: storage, dest: "uploads/", fileFilter: fileFilter});
app.post('/upload', upload.single('photo'), function(req, res, next) {
res.json({"filename": req.file.filename, "type": req.file.mimetype});
});

This endpoint will read the file input in the HTML form whose name is “photo”. This middleware will store some file information in req.file like filename and minetype. As you can see, you can set the storage and filter for it.

var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/');
},
filename: function (req, file, cb) {
var originalname = file.originalname;
var extension = originalname.split(".");
filename = req.user.username + Date.now() + '.' + extension[extension.length-1];
cb(null, filename);
}
});

In this function, you can determine the destination of the file and the name of it. Here I combine the username and timestamp as the name of the file. If you don’t specify the file name, it will be store as its original name.

function fileFilter (req, file, cb){
var type = file.mimetype;
var typeArray = type.split("/");
if (typeArray[0] == "video" || typeArray[0] == "image") {
cb(null, true);
}else {
cb(null, false);
}
}

File filter is an optional function. Let’s say you only want users to upload videos and images, then you can filter out other types of the file using mimetype.

And then you are done! Just post the HTML form to this endpoint and multer will do all the things for you. Here I’m gonna show you how to use jQuery to send an Ajax request to upload a file. I faced some problem with it before and I’ll show how to solve it.

uploadBtn.click(function (event) {
var formData = new FormData();
formData.append('photo', $('#inputFile').get(0).files[0]);
var request = $.ajax({
url: "/upload",
method: "POST",
data: formData,
contentType: false,
processData: false,
cache: false
}).done(function(data){
uploadBtn.text("Uploaded");
});
});

“uploadBtn” is the name of the submit button in the form. When the click event fires, I’ll append the content in the input field to the formData. And the most important thing is that remember to set “contentType” to false otherwise the data could not be sent to the server using the correct format.

This is a simple demo, you can check their GitHub page for detail informations.