multipart/form-data parser which supports streaming
npx @tessl/cli install tessl/npm-multiparty@4.2.00
# multiparty
1
2
multiparty is a Node.js library for parsing HTTP requests with content-type `multipart/form-data`, specifically designed for handling file uploads with streaming support. It provides a comprehensive API for processing form data without loading entire files into memory, making it ideal for efficient file upload handling in web applications.
3
4
## Package Information
5
6
- **Package Name**: multiparty
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install multiparty`
10
11
## Core Imports
12
13
```javascript
14
const multiparty = require('multiparty');
15
```
16
17
For ES modules:
18
19
```javascript
20
import * as multiparty from 'multiparty';
21
```
22
23
## Basic Usage
24
25
```javascript
26
const multiparty = require('multiparty');
27
const http = require('http');
28
29
http.createServer(function(req, res) {
30
if (req.url === '/upload' && req.method === 'POST') {
31
// Parse a file upload with callback
32
const form = new multiparty.Form();
33
34
form.parse(req, function(err, fields, files) {
35
if (err) {
36
res.writeHead(400, { 'content-type': 'text/plain' });
37
res.end('Error: ' + err.message);
38
return;
39
}
40
41
res.writeHead(200, { 'content-type': 'application/json' });
42
res.end(JSON.stringify({ fields, files }));
43
});
44
}
45
}).listen(8080);
46
```
47
48
## Architecture
49
50
multiparty is built around several key concepts:
51
52
- **Form Class**: Main parser that extends Node.js Writable stream for processing multipart data
53
- **Event-driven Architecture**: Emits events for different parts of the parsing process (parts, fields, files, errors)
54
- **Streaming Support**: Handles large file uploads without loading entire files into memory
55
- **Automatic Mode Detection**: Switches between part/field/file events based on listeners attached
56
- **Configuration Options**: Extensive options for controlling parsing behavior, limits, and file handling
57
58
## Capabilities
59
60
### Form Constructor
61
62
Creates a new multipart form parser with optional configuration.
63
64
```javascript { .api }
65
/**
66
* Creates a new multipart form parser
67
* @param {Object} options - Configuration options
68
*/
69
function Form(options);
70
71
interface FormOptions {
72
/** Encoding for incoming form fields (default: 'utf8') */
73
encoding?: string;
74
/** Maximum memory for all fields in bytes (default: 2MB) */
75
maxFieldsSize?: number;
76
/** Maximum number of fields to parse (default: 1000) */
77
maxFields?: number;
78
/** Maximum total bytes for all files (default: Infinity) */
79
maxFilesSize?: number;
80
/** Enable automatic field event emission (default: false) */
81
autoFields?: boolean;
82
/** Enable automatic file event emission (default: false) */
83
autoFiles?: boolean;
84
/** Directory for temporary file uploads (default: os.tmpdir()) */
85
uploadDir?: string;
86
}
87
```
88
89
### Form Parsing
90
91
Parses an incoming HTTP request containing multipart form data.
92
93
```javascript { .api }
94
/**
95
* Parse an HTTP request with multipart form data
96
* @param {IncomingMessage} request - Node.js HTTP request object
97
* @param {Function} [callback] - Optional callback for simplified usage
98
*/
99
form.parse(request, callback);
100
101
/**
102
* Callback function signature when provided
103
* @param {Error|null} err - Error if parsing failed
104
* @param {Object} fields - Object with field names as keys, arrays of values as values
105
* @param {Object} files - Object with field names as keys, arrays of file objects as values
106
*/
107
function parseCallback(err, fields, files);
108
```
109
110
### Form Properties
111
112
Access current parsing state and progress information.
113
114
```javascript { .api }
115
/** Current number of bytes received */
116
form.bytesReceived: number;
117
118
/** Expected total bytes from Content-Length header */
119
form.bytesExpected: number | null;
120
121
/** Current error state of the parser */
122
form.error: Error | null;
123
124
/** Array of currently opened file handles */
125
form.openedFiles: Array;
126
127
/** Total size of all parsed field data */
128
form.totalFieldSize: number;
129
130
/** Total count of parsed fields */
131
form.totalFieldCount: number;
132
133
/** Total size of all parsed file data */
134
form.totalFileSize: number;
135
```
136
137
### Event Handling
138
139
multiparty uses an event-driven architecture for handling different stages of form parsing.
140
141
```javascript { .api }
142
/**
143
* Error event - emitted when parsing encounters an error
144
* @param {Error} err - Error object with optional statusCode property
145
*/
146
form.on('error', function(err));
147
148
/**
149
* Part event - emitted for each part in the multipart data
150
* @param {ReadableStream} part - Stream for the part data
151
*/
152
form.on('part', function(part));
153
154
/**
155
* Field event - emitted for each form field (requires autoFields)
156
* @param {string} name - Field name
157
* @param {string} value - Field value
158
*/
159
form.on('field', function(name, value));
160
161
/**
162
* File event - emitted for each file upload (requires autoFiles)
163
* @param {string} name - Field name for the file
164
* @param {Object} file - File object with metadata
165
*/
166
form.on('file', function(name, file));
167
168
/**
169
* Progress event - emitted during parsing for progress tracking
170
* @param {number} bytesReceived - Total bytes received so far
171
* @param {number|null} bytesExpected - Expected total bytes
172
*/
173
form.on('progress', function(bytesReceived, bytesExpected));
174
175
/**
176
* Close event - emitted when parsing completes successfully
177
*/
178
form.on('close', function());
179
180
/**
181
* Aborted event - emitted when request is aborted
182
*/
183
form.on('aborted', function());
184
```
185
186
### Part Stream Properties
187
188
When handling part events, the part stream has additional properties for metadata.
189
190
```javascript { .api }
191
interface PartStream extends ReadableStream {
192
/** HTTP headers for this part */
193
headers: Object;
194
/** Field name for this part */
195
name: string;
196
/** Filename if this part is a file upload */
197
filename?: string;
198
/** Byte offset of this part in the request body */
199
byteOffset: number;
200
/** Size of this part in bytes (if known) */
201
byteCount?: number;
202
}
203
```
204
205
### File Object Structure
206
207
When using autoFiles mode or the parse callback, files are represented as objects with metadata.
208
209
```javascript { .api }
210
interface FileObject {
211
/** Field name for this file */
212
fieldName: string;
213
/** Original filename as reported by the client */
214
originalFilename: string;
215
/** Absolute path where the file was saved on disk */
216
path: string;
217
/** HTTP headers sent with this file */
218
headers: Object;
219
/** Size of the uploaded file in bytes */
220
size: number;
221
}
222
```
223
224
## Usage Examples
225
226
### Event-based Processing
227
228
```javascript
229
const form = new multiparty.Form({
230
uploadDir: './uploads',
231
maxFilesSize: 50 * 1024 * 1024 // 50MB limit
232
});
233
234
form.on('error', function(err) {
235
console.error('Parsing error:', err.message);
236
if (err.statusCode) {
237
res.writeHead(err.statusCode);
238
}
239
res.end('Upload failed: ' + err.message);
240
});
241
242
form.on('part', function(part) {
243
console.log('Received part:', part.name);
244
if (part.filename) {
245
console.log('File upload:', part.filename);
246
// Handle file part
247
part.on('data', function(chunk) {
248
// Process file chunk
249
});
250
} else {
251
console.log('Form field:', part.name);
252
// Handle field part
253
part.resume(); // Skip field data
254
}
255
});
256
257
form.on('close', function() {
258
console.log('Upload completed successfully');
259
res.writeHead(200);
260
res.end('Upload complete');
261
});
262
263
form.parse(req);
264
```
265
266
### Automatic File Handling
267
268
```javascript
269
const form = new multiparty.Form({
270
uploadDir: './uploads',
271
maxFilesSize: 100 * 1024 * 1024, // 100MB total
272
maxFieldsSize: 2 * 1024 * 1024 // 2MB for fields
273
});
274
275
form.on('file', function(name, file) {
276
console.log('File uploaded:', {
277
field: name,
278
filename: file.originalFilename,
279
path: file.path,
280
size: file.size
281
});
282
283
// File is automatically saved to disk at file.path
284
// You can now move it to a permanent location
285
});
286
287
form.on('field', function(name, value) {
288
console.log('Field received:', name, '=', value);
289
});
290
291
form.parse(req);
292
```
293
294
### Progress Tracking
295
296
```javascript
297
const form = new multiparty.Form();
298
299
form.on('progress', function(bytesReceived, bytesExpected) {
300
if (bytesExpected) {
301
const percent = Math.round((bytesReceived / bytesExpected) * 100);
302
console.log(`Upload progress: ${percent}% (${bytesReceived} / ${bytesExpected} bytes)`);
303
} else {
304
console.log(`Upload progress: ${bytesReceived} bytes received`);
305
}
306
});
307
308
form.parse(req);
309
```
310
311
## Error Handling
312
313
multiparty provides detailed error handling with HTTP status codes for common scenarios:
314
315
- **400 Bad Request**: Malformed multipart data, missing boundary, encoding issues
316
- **413 Payload Too Large**: Field size, file size, or field count limits exceeded
317
- **415 Unsupported Media Type**: Invalid or missing Content-Type header
318
319
```javascript
320
form.on('error', function(err) {
321
console.error('Parse error:', err.message);
322
323
// Check for specific error conditions
324
if (err.statusCode === 413) {
325
console.log('Upload too large');
326
} else if (err.statusCode === 400) {
327
console.log('Malformed request');
328
}
329
330
// Send appropriate HTTP response
331
res.writeHead(err.statusCode || 500);
332
res.end(err.message);
333
});
334
```
335
336
## Configuration Recommendations
337
338
### Production Settings
339
340
```javascript
341
const form = new multiparty.Form({
342
encoding: 'utf8',
343
maxFieldsSize: 2 * 1024 * 1024, // 2MB for form fields
344
maxFields: 100, // Limit number of fields
345
maxFilesSize: 50 * 1024 * 1024, // 50MB total for files
346
uploadDir: '/tmp/uploads' // Dedicated upload directory
347
});
348
```
349
350
### Development Settings
351
352
```javascript
353
const form = new multiparty.Form({
354
encoding: 'utf8',
355
maxFieldsSize: 10 * 1024 * 1024, // 10MB for testing
356
maxFields: 1000, // Default
357
maxFilesSize: 100 * 1024 * 1024, // 100MB for testing
358
uploadDir: './dev-uploads' // Local development directory
359
});
360
```