Node JS File Upload using express-fileupload Module

In this Node js file upload tutorial, you will learn how to upload files into the server using Node JS with the express-fileupload module.

Content of Node JS File Upload

✍ Before getting started

First, create a new folder on your desktop called node-file-upload, the name is completely up to you, basically, this is our app folder.

After that, go inside the app folder and initialize the npm, and then you have to install two packages –

  1. express Framework
  2. express-fileupload

Run the following command to install the above two packages –

npm i express express-fileupload

After installing the package, my package.json folder looks like the following.

{
  "name": "node-file-upload",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "W3jar.Com",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "express-fileupload": "^1.2.0"
  }
}

Now in the root of the app folder, you have to create a folder called uploads. Inside the uploads folder, the uploaded file will be stored.

Again in the root of the app folder, you have to create index.html for the file upload HTML Form.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Node JS File Upload - W3jar.Com</title>
    <style>
        body{
            padding: 0;
            margin: 0;
            font-family: Arial, Helvetica, sans-serif;
        }

        .container{
            max-width: 400px;
            margin: 0 auto;
            padding: 20px;
            text-align: center;
        }

        [type="file"]{
            border: 1px solid #cccccc;
            background: #f9f9f9;
            width: 100%;
            padding: 10px;
            margin-bottom: 10px;
            font-size: 18px;
            border-radius: 2px;
        }
        [type="submit"]{
            cursor: pointer;
            font-size: 16px;
            background: #5d13e7;
            color: #ffffff;
            padding: 10px 20px;
            border: 1px solid rgba(0,0,0,.1);
            border-radius: 3px;
            box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
        }

    </style>
</head>
<body>
    <div class="container">
        <h1>Node.js File Upload</h1>

        <form action="" method="POST" enctype="multipart/form-data">
            <input type="file" name="target_file" required>
            <input type="submit" value="Upload">
        </form>
        
    </div>
</body>
</html>
File upload HTML Form
HTML Form in Browser

1. Simple Node JS File Upload

const express = require('express');
const fileUpload = require('express-fileupload');
const path = require('path');
const app = express();

app.use(fileUpload({
    useTempFiles : true,
    tempFileDir : path.join(__dirname,'tmp'),
}));

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'index.html'));
});

app.post('/', (req, res) => {
    
    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send('No files were uploaded.');
    }

    // Accessing the file by the <input> File name="target_file"
    let targetFile = req.files.target_file;

    //mv(path, CB function(err))
    targetFile.mv(path.join(__dirname, 'uploads', targetFile.name), (err) => {
        if (err)
            return res.status(500).send(err);
        res.send('File uploaded!');
    });
  
});

app.listen(3000, () => console.log('Your app listening on port 3000'));

2. Limiting the upload size

In the following code, the maximum upload size is 1MB

const express = require('express');
const fileUpload = require('express-fileupload');
const fs = require('fs');
const path = require('path');
const app = express();

app.use(fileUpload({
    useTempFiles : true,
    tempFileDir : path.join(__dirname,'tmp'),
}));

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'index.html'));
});

app.post('/', (req, res) => {
    
    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send('No files were uploaded.');
    }

    let targetFile = req.files.target_file;

    // Checking File Size (Max Size - 1MB)
    if(targetFile.size > 1048576){

        // Deleting Temporary File
        fs.unlinkSync(targetFile.tempFilePath);
        return res.status(413).send("File is too Large");
    }

    targetFile.mv(path.join(__dirname, 'uploads', targetFile.name), (err) => {
        if (err)
            return res.status(500).send(err);
        res.send('File uploaded!');
    });
  
});

app.listen(3000, () => console.log('Your app listening on port 3000'));

3. Rename the file before uploading

In the following example, we will rename those files that already exist in the uploads folder with the same name and extension. So that the new file cannot replace the old file.

const express = require('express');
const fileUpload = require('express-fileupload');
const fs = require('fs');
const path = require('path');
const app = express();

app.use(fileUpload({
    useTempFiles : true,
    tempFileDir : path.join(__dirname,'tmp'),
}));

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'index.html'));
});

app.post('/', (req, res) => {
    
    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send('No files were uploaded.');
    }

    let targetFile = req.files.target_file;
    let extName = path.extname(targetFile.name);
    let baseName = path.basename(targetFile.name, extName);
    let uploadDir = path.join(__dirname, 'uploads', targetFile.name);

    if(targetFile.size > 1048576){
        fs.unlinkSync(targetFile.tempFilePath);
        return res.status(413).send("File is too Large");
    }

    // Renaming the file
    let num = 1;
    while(fs.existsSync(uploadDir)){
        uploadDir = path.join(__dirname, 'uploads', baseName + '-' + num + extName);
        num++;
    }

    targetFile.mv(uploadDir, (err) => {
        if (err)
            return res.status(500).send(err);
        res.send('File uploaded!');
    });
  
});

app.listen(3000, () => console.log('Your app listening on port 3000'));

4. Upload only specific types of files

In the following example, we will be allowed to upload only images. Such as – png, jpg, jpeg, gif

const express = require('express');
const fileUpload = require('express-fileupload');
const fs = require('fs');
const path = require('path');
const app = express();

app.use(fileUpload({
    useTempFiles : true,
    tempFileDir : path.join(__dirname,'tmp'),
}));

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'index.html'));
});

app.post('/', (req, res) => {
    
    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send('No files were uploaded.');
    }

    let targetFile = req.files.target_file;
    let extName = path.extname(targetFile.name);
    let baseName = path.basename(targetFile.name, extName);
    let uploadDir = path.join(__dirname, 'uploads', targetFile.name);

    let imgList = ['.png','.jpg','.jpeg','.gif'];
    // Checking the file type
    if(!imgList.includes(extName)){
        fs.unlinkSync(targetFile.tempFilePath);
        return res.status(422).send("Invalid Image");
    }

    if(targetFile.size > 1048576){
        fs.unlinkSync(targetFile.tempFilePath);
        return res.status(413).send("File is too Large");
    }

    let num = 1;
    while(fs.existsSync(uploadDir)){
        uploadDir = path.join(__dirname, 'uploads', baseName + '-' + num + extName);
        num++;
    }

    targetFile.mv(uploadDir, (err) => {
        if (err)
            return res.status(500).send(err);
        res.send('File uploaded!');
    });
  
});

app.listen(3000, () => console.log('Your app listening on port 3000'));

Leave a Reply