Install busboy via npm
masterInstall the busboy module using npm to parse incoming HTML form data in Node.js.
npm install busboyrepository·master·Indexed 23 days ago
https://github.com/mscdex/busboyA high-performance streaming parser for HTML form data in Node.js, specifically supporting multipart/form-data and application/x-www-form-urlencoded. Version 1.6.0 provides a Writable form parser stream that emits events for files and fields, with configurable limits for field size, file size, and the number of parts.
Install the busboy module using npm to parse incoming HTML form data in Node.js.
npm install busboyThis example demonstrates how to set up a basic HTTP server that uses busboy to listen for POST requests containing multipart form data, logging both files and text fields.
const http = require('http');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
console.log('POST request');
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const { filename, encoding, mimeType } = info;
console.log(
`File [${name}]: filename: %j, encoding: %j, mimeType: %j`,
filename,
encoding,
mimeType
);
file.on('data', (data) => {
console.log(`File [${name}] got ${data.length} bytes`);
}).on('close', () => {
console.log(`File [${name}] done`);
});
});
bb.on('field', (name, val, info) => {
console.log(`Field [${name}]: value: %j`, val);
});
bb.on('close', () => {
console.log('Done parsing form!');
res.writeHead(303, { Connection: 'close', Location: '/' });
res.end();
});
req.pipe(bb);
} else if (req.method === 'GET') {
res.writeHead(200, { Connection: 'close' });
res.end(`
<html
<head></head>
<body
<form method="POST" enctype="multipart/form-data">
<input type="file" name="filefield"><br />
<input type="text" name="textfield"><br />
<input type="submit">
</form>
</body>
</html>
`);
}
}).listen(8000, () => {
console.log('Listening for requests');
});This example demonstrates how to pipe incoming file streams directly to a write stream on the local filesystem using fs.createWriteStream.
const { randomFillSync } = require('crypto');
const fs = require('fs');
const http = require('http');
const os = require('os');
const path = require('path');
const busboy = require('busboy');
const random = (() => {
const buf = Buffer.alloc(16);
return () => randomFillSync(buf).toString('hex');
})();
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const saveTo = path.join(os.tmpdir(), `busboy-upload-${random()}`);
file.pipe(fs.createWriteStream(saveTo));
});
bb.on('close', () => {
res.writeHead(200, { 'Connection': 'close' });
res.end(`That's all folks!`);
});
req.pipe(bb);
return;
}
res.writeHead(404);
res.end();
}).listen(8000, () => {
console.log('Listening for requests');
});The busboy function creates and returns a new Writable form parser stream. It requires a configuration object. Note that if the headers in the config are missing a supported Content-Type or a boundary for multipart/form-data, the function will throw an exception.
Configuration Options:
| Property | Type | Description |
|---|---|---|
headers | object | The HTTP headers of the incoming request. |
highWaterMark | integer | High water mark for the parser stream. (Default: node's stream.Writable default) |
fileHwm | integer | High water mark for individual file streams. (Default: node's stream.Readable default) |
defCharset | string | Default character set if none is defined. (Default: 'utf8') |
defParamCharset | string | Default character set for multipart form part header parameters. (Default: 'latin1') |
preservePath | boolean | Whether to preserve paths in filenames from file parts. (Default: false) |
limits | object | Object containing data limits (see Limits) |
Limits Configuration (limits object):
| Property | Type | Description |
|---|---|---|
fieldNameSize | integer | Max field name size in bytes. (Default: 100) |
fieldSize | integer | Max field value size in bytes. (Default: 1048576 / 1MB) |
fields | integer | Max number of non-file fields. (Default: Infinity) |
fileSize | integer | Max file size in bytes for multipart forms. (Default: Infinity) |
files | integer | Max number of file fields. (Default: Infinity) |
parts | integer | Max number of parts (fields + files). (Default: Infinity) |
headerPairs | integer | Max number of header key-value pairs to parse. (Default: 2000) |
const busboy = require('busboy');
const bb = busboy({ headers: req.headers });Busboy emits specific events when configured limits are reached. Once these limits are hit, no further 'file' or 'field' events will be emitted.
partsLimit(): Emitted when limits.parts is reached.filesLimit(): Emitted when limits.files is reached. No more 'file' events will be emitted.fieldsLimit(): Emitted when limits.fields is reached. No more 'field' events will be emitted.The main export of busboy is a function that initializes a parser instance based on the provided Content-Type header. You must provide a configuration object containing a headers object with a valid content-type string.
Supported content types are automatically detected (e.g., multipart/form-data or application/x-www-form-urlencoded).
Available configuration options in the cfg object:
headers: (Required) An object containing request headers. Must include content-type.limits: Configuration for parsing limits.highWaterMark: Internal buffer size for the parser.fileHwm: Internal buffer size for files.defCharset: Default character set.defParamCharset: Default character set for parameters.preservePath: Boolean to determine if file paths should be preserved.The Busboy initialization function throws errors in the following scenarios:
cfg.headers is not an object, is null, or if cfg.headers['content-type'] is not a string.Missing Content-Typecontent-type header cannot be parsed.Malformed content typecontent-type does not match any supported types (like multipart or urlencoded).Unsupported content type: <header-value>The field event is emitted for each new non-file field found in the form.
Arguments:
name (string): The form field name.value (string): The string value of the field.info (object): Contains metadata:nameTruncated (boolean): Whether name was truncated due to limits.fieldNameSize.valueTruncated (boolean): Whether value was truncated due to limits.fieldSize.encoding (string): The 'Content-Transfer-Encoding' value.mimeType (string): The 'Content-Type' value.bb.on('field', (name, val, info) => {
console.log(`Field [${name}]: value: %j`, val);
});The file event is emitted for each new file found in the form.
Arguments:
name (string): The form field name.stream (Readable): A stream containing the file's raw data (no transformations like base64 are applied).info (object): Contains metadata:filename (string): The file's filename. WARNING: Do not use this value directly for file paths as it may contain malicious input. Generate your own safe filenames.encoding (string): The 'Content-Transfer-Encoding' value.mimeType (string): The 'Content-Type' value.Important Notes:
stream (e.g., via .pipe() or stream.resume()) regardless of whether you need the data. If you do not, the 'finish'/'close' events on the parser stream will never fire.limits.fileSize is exceeded, the stream will have a truncated: true property and the parser will emit a 'limit' event.