This page looks best with JavaScript enabled

Node.JS: Busboy, reading file and text parameters

 ·  ☕ 3 min read  ·  ✍️ Iskander Samatov

Recently I had a task of uploading an image to my cloud storage using Express. I knew I had to use multipart parameter for the file but I also had to pass a security token to make sure the request came from an authorized source. I went with the connect-busboy library. I implemented the solution to read both file and text parameters and in this tutorial I will show you how.

Dependencies

  • "connect-busboy": "^0.0.2"
  • "express": "^4.16.3"

Process

1. Setup a post method

First set up a post method using Express and add the busboy middleware to the method. I’m adding the middleware specifically to the method because I’m only using busboy to handle file upload requests for any other requests I use <a href="https://www.npmjs.com/package/body-parser">body-parser</a>:

1
2
app.post('/file/save', busboy({ immediate: true }), (req, res, next) => {
}

immediate: true makes sure that the parsing begins immediately on the request.

2. Parse request parameters

To read form parameters we use req.busboy.on() method. The method accepts 2 parameters:

  1. The name of the event triggered by parsing the parameters
  2. The callback function when the event is triggered

First we add a way to read the file type parameters:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
let fileData = null;
req.busboy.on('file', (fieldName, file) => {
  file.on('data', (data) => {
    if (fileData === null) {
      fileData = data;
    } else {
      fileData = Buffer.concat([fileData, data]);
    }
  });
});

Whenever busboy parses parameter of type file we check for the data value and if it’s not null we concatenate it in into the existing fileData buffer variable. This is done for files that are too big to get parsed all at once.

Since I’m only passing one parameter of type file I have no need to check for fieldName. If you have multiple files passed then you should check fieldName to make sure you’re assigning data to the correct buffer.

Next we implement a way to read the security token as a text field parameter:

1
2
3
4
5
6
let token = null;
req.busboy.on('field', (fieldName, value) => {
  if (fieldName === 'token') {
    token = value;
  }
});

Here it’s pretty straightforward — busboy parses field type parameter and we check the fieldName value to make sure it’s our token

Finally we implement our on('finish') method:

1
2
3
4
5
req.busboy.on('finish', () => {
  if (!fileData) next(new Error('file binary data cannot be null'));
  if (!token) next(new Error('No security token was passed'));
  //TODO: use your parsed parameters to complete the request
});

This method lets us know that busboy is finished parsing all the parameters. Make sure to put all the code that you plan on executing after the parameters are done parsing here. Otherwise you might have files that are not fully parsed.

And that’s pretty much everything you should need to parse multiple parameters using busboy. Here’s the full method for you:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
app.post('/profile-image/save', busboy({ immediate: true }), (req, res, next) => {
  if (!req.busboy) throw new Error('file binary data cannot be null');
  let fileData = null;
  let token = null;
  req.busboy.on('file', (fieldName, file) => {
    file.on('data', (data) => {
      if (fileData === null) {
        fileData = data;
      } else {
        fileData = Buffer.concat([fileData, data]);
      }
    });
  });
  req.busboy.on('field', (fieldName, value) => {
    if (fieldName === 'token') {
      token = value;
    }
  });
  req.busboy.on('finish', () =>{
    if (!fileData) next(new Error('file binary data cannot be null'));
    if (!token) next(new Error('No security token was passed'));
    //TODO: use your parsed parameters to complete the request
  });
});

Hope this post was helpful. Thank you!

Share on

Software Development Tutorials
WRITTEN BY
Iskander Samatov
The best up-to-date tutorials on web and mobile development.