Upload Files in Node.js

How to Upload Files in Node.js using express-fileupload?

File uploads are a fundamental part of many web applications, and Node.js provides a simple way to handle them. One of the popular libraries for handling file uploads in Node.js is “express-fileupload“.

In this step-by-step guide, you will learn how to set up and use express-fileupload to enable file uploads in your Node.js application.

Table of Contents #
  1. Create a Node.js Project
  2. Setting Up Express and express-fileupload
  3. Creating an HTML Form for File Upload
  4. Handling File Uploads in Node.js
  5. Handling File Upload Errors
  6. Testing the Application
  7. More on express-fileupload

Before getting started, make sure you have installed the Node.js, and NPM on your system.

1. Create a Node.js Project

Begin by creating a new directory for your Node.js project. Open your terminal and execute the following commands:

mkdir file-upload-app
cd file-upload-app
npm init -y

This will create a new Node.js project with a package.json file.

Here is the file-upload-app folder structure:

node file upload folder structure

2. Setting Up “Express” and “express-fileupload”

Now that your Node.js project is initialized, you need to install the required dependencies. Run the following command in your project directory:

npm install express express-fileupload

This will install the Express.js framework and express-fileupload middleware.

3. Creating an HTML Form for File Upload

To enable users to upload files, you need to create an HTML form that allows them to select and send files. Create a new HTML file (e.g., index.html) in your project directory with the following content:

<!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</title>
        <link
            rel="stylesheet"
            href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css"
        />
    </head>
    <body>
        <form action="/upload" method="post" enctype="multipart/form-data">
            <label for="myFile">Choose a File</label>
            <input type="file" name="myfile" id="myFile" />
            <input type="submit" value="Upload" />
        </form>
    </body>
</html>

In this form, we set the enctype attribute to "multipart/form-data" to allow file uploads. The form will send a POST request to the "/upload" route when the user clicks the “Upload!” button.

4. Handling File Uploads in Node.js

Now, it’s time to set up your Node.js application to handle file uploads. Create a JavaScript file (e.g., app.js) and add the following code:

const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();
const port = process.env.PORT || 3000;

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Enable file uploads
app.use(fileUpload());

// Serve the HTML form
app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html');
});

// Handle file uploads
app.post('/upload', (req, res) => {
    // If there is no file to upload
    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send('No files were uploaded.');
    }

    const targetFile = req.files.myfile;
    // if targetFile is undefined
    if (!targetFile) return res.send('myfile is missing!');

    const fileName = targetFile.name;
    const uploadPath = __dirname + '/uploads/';
    const filePathName = uploadPath + fileName;

    targetFile.mv(filePathName, (err) => {
        // If there is an error
        if (err) {
            return res.status(500).send(err.message);
        }
        res.send('File uploaded!');
    });
});

app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});
  • This code sets up a basic Express.js server,
  • Serves the HTML form (index.html) on the root / route,
  • Handles file uploads on the /upload route,
  • If a file is uploaded successfully, it’s moved to the /uploads directory.

In the code, you can see the targetFile.mv() function which is responsible for uploading files. This .mv() function takes two parameters –

  1. filePathName – Full path to the directory (where the file will be stored) with the name.
  2. callback – A callback function with error parameter for handling errors.

5. Handling File Upload Errors

The code provided (app.js) includes basic error handling. If there are no files in the request or an error occurs during the file upload, the server responds with appropriate status codes and error messages.

You can also use the try-catch to handle errors:

app.post('/upload', async (req, res) => {
    try {
        const targetFile = req.files.myfile;
        await targetFile.mv();
        res.send('File uploaded!');
    } catch (e) {
        return res.status(500).send(err.message);
    }
});

6. Testing the Application

To test the application, run your Node.js server using the following command:

node app.js

Visit http://localhost:3000 in your web browser, and you should see the file upload form. Select a file and click “Upload!” to test the file upload functionality.


More on express-fileupload

1. Store temporary files:

By default, this module uploads files into RAM. Turning on the useTempFiles option by setting it to True enables the use of temporary files instead of utilizing RAM.

This option prevents memory overflow issues when uploading large files or when uploading multiple files simultaneously.

// From this
app.use(fileUpload());

// To this
app.use(
    fileUpload({
        useTempFiles: true,
    })
);

By default this module uses 'tmp' folder in the current working directory. If you want to use custom folder to store temporary files use tempFileDir along with the useTempFiles.

app.use(fileUpload({
    useTempFiles : true,
    tempFileDir : __dirname + '/tmp_folder',
}));

2. Limiting the upload file size

You can limit the upload file size with the help of the limits:in bytes option. Here is an example:

// Enable file uploads
app.use(
    fileUpload({
        useTempFiles: true,
        limits: { fileSize: 1 * 1024 * 1024 }, // Maximum file size is 1MB
    })
);

// Handle file uploads
app.post('/upload', (req, res) => {

    const targetFile = req.files.myfile;
    // If the file is over the size limit
    if (targetFile.truncated) {
        return res.send('File is too large max size is 1MB');
    }

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

});

3. Rename the file before uploading

We need to rename the file before storing, So that the new file cannot replace the old file, and it is quite easy task. Here is an example of renaming file while using express-fileupload in node.js:

app.post('/upload', (req, res) => {
    const targetFile = req.files.myfile;

    // Rename the file to be uploaded
    const fileName = `${new Date().getTime()}-${targetFile.name}`;

    const uploadPath = __dirname + '/uploads/';
    const filePathName = uploadPath + fileName;

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

In the example, the current timestamp is appended to the file name and then the file is uploaded.

4. Upload only specific types of files

If you want to upload only specific types of files, such as only images (png, jpg, webp), we need to check the file extension before uploading. Here is an example:

const targetFile = req.files.myfile;
const extensionName = path.extname(targetFile.name); // fetch the file extension
const allowedExtension = ['.png','.jpg','.webp'];

if(!allowedExtension.includes(extensionName)){
    return res.status(422).send("Invalid Image");
}

You have successfully set up file uploads in your Node.js application using express-fileupload. You can further enhance your application by implementing additional features such as file type validation and user authentication for secure file uploads.