• Node.js Video Tutorials

Node.js - Upload Files



In many web applications, a user from client machine is required to upload file (such as the user uploading images and videos with Facebook or Instagram apps) to the server. There are a number of open-source modules available on the NPM registry, with which the feature of uploading files can be enabled in a Node.js application. The formidable module offers a convenient API to handle the file uploads. The formidable module can be imported in a core Node.js module along with the built-in http module, as well as the Express app.

Formidable

The Formidable module is a fast and streaming multipart parser, capable of automatically writing file uploads to the disk. It has a low memory footprint, with efficient error handling mechanism.

As a first step, install the formidable module with the following command −

npm install formidable

In this chapter, the example usage of Formidable module in a node.js application that includes http module and in an ExpressJs application are shown below −

with Node.js http module

The following example calls the createServer() function to launch the Node.JS server and renders a multipart HTML form for the user to choose the file to be uploaded.

When the file is submitted, the form data is parsed and the uploaded file is copied in the default location in the disk.

var http = require('http');
var formidable = require('formidable');

var errors = formidable.formidableErrors;

const server = http.createServer(async (req, res) => {
   if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') {
      // parse a file upload
      const form = new formidable.IncomingForm();
      let fields;
      let files;
      try {
         [fields, files] = await form.parse(req);
      } catch (err) {

         res.writeHead(err.httpCode || 400, { 'Content-Type': 'text/plain' });
         res.end(String(err));
         return;
      }
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ fields, files }, null, 2));
      return;
   }

   // show a file upload form
   res.writeHead(200, { 'Content-Type': 'text/html' });
   res.end(`
      <h2>With Node.js <code>"http"</code> module</h2>
      <form action="/api/upload" enctype="multipart/form-data" method="post">
      <div>Text field title: <input type="text" name="title" /></div>
      <div>File: <input type="file" name="multipleFiles" multiple="multiple" /></div>
      <input type="submit" value="Upload" />
      </form>
   `);
});
server.listen(5000, () => {
   console.log('Server listening on http://localhost:5000/ ...');
});

As the application is run, the browser shows the following form to choose a file to be uploaded.

Nodejs http Module

After successful upload operation, the browser shows the following result −

{
  "fields": {
      "title": [
         "test"
      ]
   },
   "files": {
      "multipleFiles": [
         {
            "size": 4203211,
            "filepath": "C:\\Users\\user\\AppData\\Local\\Temp\\930f2f754006b790729e0d200",
            "newFilename": "930f2f754006b790729e0d200",
            "mimetype": "image/png",
            "mtime": "2023-12-24T08:04:09.856Z",
            "originalFilename": "1.png"
         }
      ]
   }
}

with Express.js

The simplest usage of formidable module in an Express.JS code is as follows −

import express from 'express';
import formidable from 'formidable';

const app = express();

app.get('/', (req, res) => {
   res.send(`
      <h2>With <code>"express"</code> npm package</h2>
      <form action="/api/upload" enctype="multipart/form-data" method="post">
      <div>Text field title: <input type="text" name="title" /></div>
      <div>File: <input type="file" name="someExpressFiles" multiple="multiple" /></div>
      <input type="submit" value="Upload" />
      </form>
   `);
});
app.post('/api/upload', (req, res, next) => {
   const form = formidable({});

   form.parse(req, (err, fields, files) => {
      if (err) {
         next(err);
         return;
      }
      res.json({ fields, files });
   });
});

app.listen(5000, () => {
   console.log('Server listening on http://localhost:5000 ...');
});

You can also install and use body-parser module to parse the multipart HTML form data in the uploading process.

Multer

Another useful NPM module that is capable of handling file uploads is called Multer. Users can upload either single or multiple files at a time.

To install, use the following command −

npm install multer

In the beginning of an Express app, include muletr and declare the Multer object.

const multer  = require('multer')
const upload = multer({ dest: 'uploads/' })

Assuming that you have a route to handle a GET request and display a multipart HTML form that posts the form to /upload route, add the following function to handle POST request −

app.post("/upload", upload.single("myFile"), (req, res) => {
   console.log("Body: ", req.body);
   console.log("File: ", req.file);
   res.send("File successfully uploaded.");
});

To store the uploaded file at a specified location instead of the default location of the temporary file, configure the Multer location as below −

var storage = multer.diskStorage({   
   destination: function(req, file, cb) { 
      // destination is used to specify the path of the directory in which the files have to be stored
      cb(null, './uploads');    
   }, 
   filename: function (req, file, cb) { 
      // It is the filename that is given to the saved file.
      cb(null , file.originalname);   
   }
});

// Configure storage engine instead of dest object.
const upload = multer({ storage: storage })
Advertisements