Oct 19, 2014

Ketan Patel

File Upload in Node.js Using Formidable

In this tutorial we'll learn how to upload file in Node.js using Formidable. Let me introduce you with Formidable - Its a node.js module used for parsing form data, especially file uploads.


Some Features of Formidable:



  • Fast and non-buffering multipart parser
  • Low memory footprint
  • Automatically writing file uploads to disk
  • Very high test coverage
  • Graceful error handling 


Installation 



If you are using framework like express then it might be already included in it.You can install it via npm like this,


npm install formidable@latest


Detail description about Formidable is given here. A simple example has already been given there. We'll use the same in our tutorial.


In native fs module of node.js , some file system methods were not present. So we are going to use one another module called "fs-extra" which adds some extra file system methods. You can install fs-extra like this ,


npm install fs-extra



File Upload Process


The code for file upload process is very simple and easy to understand.In very first step we will create node.js server which display our file upload form.


// Required Modules
var formidable = require('formidable'),
    http = require('http'),
    util = require('util'),
    fs   = require('fs-extra');
// create server 
http.createServer(function(req, res) {
 /* Displaying file upload form. */
  res.writeHead(200, {'content-type': 'text/html'});
  res.end(
    '<form action="/upload" method="post" enctype="multipart/form-data">'+
    '<input type="file" name="upload" multiple="multiple"><br>'+
    '<input type="submit" value="Upload File">'+
    '</form>'
  );
}).listen(8080);




Above code will display simple file upload form without any processing.Now Formidable will come into the picture for file upload processing. 


// Required Modules
var formidable = require('formidable'),
    http = require('http'),
    util = require('util'),
    fs   = require('fs-extra');

     // create server  
     http.createServer(function(req, res) {
  
   // Form uploading Process code
   //Upload route
   if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
    
 // creates a new incoming form. 
 var form = new formidable.IncomingForm();
 
 // parse a file upload
    form.parse(req, function(err, fields, files) {
      res.writeHead(200, {'content-type': 'text/plain'});
      res.write('Upload received :\n');
      res.end(util.inspect({fields: fields, files: files}));
    });
    return;
  }
  /* Displaying file upload form. */
  res.writeHead(200, {'content-type': 'text/html'});
  res.end(
    '<form action="/upload" method="post" enctype="multipart/form-data">'+
    '<input type="file" name="upload" multiple="multiple"><br>'+
    '<input type="submit" value="Upload">'+
    '</form>'
  );
}).listen(8080);




In above code we're checking that the requesting url is '/upload' and the method is 'post'. After that we are using the parse method in order to process the incoming node request.

Using the util.inspect method, we just output the processed form details to the browser. On Running the above code on my machine,it displays the following in the browser.


Upload received :
{ fields: {},
  files: 
   { upload: 
      { domain: null,
        _events: {},
        _maxListeners: 10,
        size: 14684,
        path: 'C:\\Users\\kp\\AppData\\Local\\Temp\\2ebf41af0b2d926432c16c70ae8f6de4',
        name: 'nodejs.png',
        type: 'image/png',
        hash: null,
        lastModifiedDate: Sun Oct 19 2014 13:56:17 GMT+0530 (India Standard Time),
        _writeStream: [Object] } } }



As you can see the file has been uploaded to a temporary directory in my 'Users' folder with the name '2ebf41af0b2d926432c16c70ae8f6de4'. Now we'll copy the same to our desired location. To accomplish this we need to use the node 'fs-extra' module, which makes it easier to copy files in node.js.

// Required Modules
var formidable = require('formidable'),
    http = require('http'),
    util = require('util'),
    fs   = require('fs-extra');

     // create server  
     http.createServer(function(req, res) {
  
   // Form uploading Process code
   //Upload route
   if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
    
 // creates a new incoming form. 
 var form = new formidable.IncomingForm();
 
 // parse a file upload
    form.parse(req, function(err, fields, files) {
      res.writeHead(200, {'content-type': 'text/plain'});
      res.write('Upload received :\n');
      res.end(util.inspect({fields: fields, files: files}));
    });
 form.on('end', function(fields, files) {
        /* Temporary location of our uploaded file */
        var temp_path = this.openedFiles[0].path;
        /* The file name of the uploaded file */
        var file_name = this.openedFiles[0].name;
        /* Location where we want to copy the uploaded file */
        var new_location = 'C:/Program Files/nodejs/demo/uploads/';
        fs.copy(temp_path, new_location + file_name, function(err) {  
            if (err) {
                console.error(err);
            } else {
                console.log("success!")
            }
        });
    });
    return;
  }
  /* Displaying file upload form. */
  res.writeHead(200, {'content-type': 'text/html'});
  res.end(
    '<form action="/upload" method="post" enctype="multipart/form-data">'+
    '<input type="file" name="upload" multiple="multiple"><br>'+
    '<input type="submit" value="Upload">'+
    '</form>'
  );
}).listen(8080);




That's it...!! just run the this file through command and go to http://localhost:8080 , upload any file. It will be uploaded and copied to your destination folder.


If you like this post, then please share it..

Ketan Patel

About Ketan Patel -

I have developed a wide range of websites using CorePHP, Opencart, CakePHP and CodeIgniter including sites for startup companies and small businesses. Apart from my blogging life, I like to read Novels, Listening music and Net surfing.

Subscribe to this Blog via Email :