Use Express to process file uploads in forms

How to manage storage and processing of files uploaded through forms in Express

This is an example of an HTML form that allows users to upload files:

<form method="POST" action="/submit-form" enctype="multipart/form-data">
  <input type="file" name="document" />
  <input type="submit" />
</form>

Don't forget to addenctype="multipart/form-data"To the form, otherwise the file will not be uploaded

When the user presses the "Submit" button, the browser will automatically create aPOSTClaim/submit-formThe URL on the same source of the page. The browser sent the included data, but did not encode it into a regular formatapplication/x-www-form-urlencoded, butmultipart/form-data.

Server-side processing of multi-part data can be tricky and error-prone, so we will use a method calledpowerful.This is the GitHub repository, It has more than 4,000 stars and is well maintained.

You can install it using the following methods:

npm install formidable

Then include it in your Node.js file:

const express = require('express')
const app = express()
const formidable = require('formidable')

now atPOSTEndpoint/submit-formRoute, we instantiated a new powerful form usingformidable.IncomingForm():

app.post('/submit-form', (req, res) => {
  new formidable.IncomingForm()
})

After doing this, we need to be able to parse the form. We can do this synchronously by providing a callback, which means that all files will be processed, and once the hard work is done, they can be made available:

app.post('/submit-form', (req, res) => {
  new formidable.IncomingForm().parse(req, (err, fields, files) => {
    if (err) {
      console.error('Error', err)
      throw err
    }
    console.log('Fields', fields)
    console.log('Files', files)
    for (const file of Object.entries(files)) {
      console.log(file)
    }
  })
})

Alternatively, you can use events instead of callbacks. For example, to be notified when each file is parsed or other events occur (such as file processing completed, non-file fields received, or errors occur):

app.post('/submit-form', (req, res) => {
  new formidable.IncomingForm().parse(req)
    .on('field', (name, field) => {
      console.log('Field', name, field)
    })
    .on('file', (name, file) => {
      console.log('Uploaded file', name, file)
    })
    .on('aborted', () => {
      console.error('Request aborted by the user')
    })
    .on('error', (err) => {
      console.error('Error', err)
      throw err
    })
    .on('end', () => {
      res.end()
    })
})

No matter which method you choose, you will get one or more Formidable.File objects that provide you with information about the uploaded file. These are some methods you can call:

  • file.size, File size (in bytes)
  • file.path, The path where the file is written
  • file.name,file name
  • file.type, The MIME type of the file

The path defaults to the temporary folder, if you listen to the path, you can modify the path.fileBeginevent:

app.post('/submit-form', (req, res) => {
  new formidable.IncomingForm().parse(req)
    .on('fileBegin', (name, file) => {
        file.path = __dirname + '/uploads/' + file.name
    })
    .on('file', (name, file) => {
      console.log('Uploaded file', name, file)
    })
    //...
})

Download mine for freeExpress.js manual


More crash tutorials: