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 mechanisms you have seen yet.

How to perform file upload using Node.js?

We will be going to use the Express framework and middleware called “multer”. This middleware is designed for handling multipart/form-data.

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

Creating an Application for File Upload

Let’s create a simple Node.js project, where we will have an express web server that does the task of routing and other stuff, multer will take care of the file handling and HTML for uploading the data.

Create a file package.json, and write the below code inside it.

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 the folder and type npm install to install the required module mentioned in the package.json file.

Writing Code for Handling File Upload

Once you have done this, you have to create a new JavaScript file server.js for writing the backend code and a file index.html to write HTML code for the frontend to create a form, so we can select the file we want to upload.

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

<!DOCTYPE html>
<html>

<head>
    <title>File Upload</title>
</head>

<body>
    <h1>File Upload Example</h1>
    <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>
</body>

</html>

Run the Application:

To execute the code, run the following command in a terminal.

node server.js

Now, open any browser and visit localhost:3000 to view the app. Select the file and check the uploads folder. Your file must be present in that directory!

Output:

Output of File Upload Application

Code Explanation:

In our Server.js file, we have configured multer, which is the first file upload process. We have made a custom middleware function to choose the storage engine which is diskStorage because we want files to store in a disk and append the file name with the current date just to keep the uniqueness of files.

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

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

We are initializing the multer in our /api/photo/ router and in the callback we are receiving the incoming error. If there is no error that means the 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 using Multer

To perform validation on the server end, multer provides limits array parameters which have the following parameters.

  • 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

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


Example:

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

Now let’s see some frequently asked questions on related topics.

Frequently Asked Questions (FAQs)

How to upload a file in NodeJS using FS?

If you want to upload a file only using the FS module, then you have to manually write the code for reading the file’s content using the fs.readFile or fs.createReadStream methods and then write it somewhere else using the fs.writeFile or fs.createWriteStream methods. 

How to upload large files in NodeJS?

You can use the FS module to upload large files in small pieces and write them using stream to a temporary location, after uploading the whole file you can then transfer it to the desired destination.

What is file upload bypass?

Whenever you upload files, some security measures must be followed. For instance, certain file types may not be permitted. Avoiding these security measures while uploading files is called file upload bypass. This can be done by manipulating the upload process and conditions.

Why do we use multer in NodeJS?

The “multer” is a popular Node.js middleware used for handling file uploads. It is one of the fastest modules that can efficiently parse the “multipart/form-data”. In addition, it also offers more advanced features such as setting the upload file size, renaming the file, etc. It also has the best compatibility with Express.

Is NodeJS good for file processing?

Node.js is asynchronous in nature, making it perfect for file processing. Its non-blocking I/O model allows us to process files without blocking the rest of the operation which is best suited for large-scale applications where we have to process a lot of files continuously.

What is faster than NodeJS?

There can be many languages that can be faster than Node.js like C++, Go, Rust, etc, but then it also depends on the specific task being performed. However, for handling files, Node.js can be considered the fastest.

Why is NodeJS so difficult?

Node.js can be difficult for beginners as it introduced many new concepts which are not much used in other programming languages. There is asynchronous as well as synchronous for the same task, so it creates confusion. However, you can refer to the tutorials on our website where we have explained each and every concept of Node.js in a very simple and beginner’s way which makes mastering Node.js quite easy.

Conclusion

In this tutorial, we have seen how to handle file upload in Node.js and Express App. We have used an Express middleware “multer” for processing file uploads, which supports multiple files and easily parses the “multipart/form-data“. For further clearing your dought regarding the topic, you can also read the above FAQs. At last, we hope you have enjoyed reading the content.

Reference

Multer GitHub Official Page

Pankaj Kumar
Pankaj Kumar
Articles: 208