0
# File Uploads
1
2
Multipart form data support for file uploads and form submissions with comprehensive options for handling files, streams, and buffers.
3
4
## Capabilities
5
6
### File Attachment
7
8
Methods for attaching files to multipart requests.
9
10
```javascript { .api }
11
/**
12
* Attach a file to the request as multipart/form-data
13
* @param {string} field - Form field name
14
* @param {string|Buffer|Stream} file - File path, Buffer, or Stream
15
* @param {string|object} [options] - Filename string or options object
16
* @param {string} [options.filename] - Custom filename
17
* @param {string} [options.contentType] - Custom content type
18
* @returns {Request} Request instance for chaining
19
*/
20
Request.prototype.attach(field, file, options?): Request;
21
22
/**
23
* Add a form field to multipart request
24
* @param {string} name - Field name
25
* @param {string|number|boolean} value - Field value
26
* @returns {Request} Request instance for chaining
27
*/
28
Request.prototype.field(name, value): Request;
29
```
30
31
**Usage Examples:**
32
33
```javascript
34
const superagent = require('superagent');
35
const fs = require('fs');
36
37
// Upload file from filesystem
38
superagent
39
.post('https://api.example.com/upload')
40
.attach('file', '/path/to/document.pdf');
41
42
// Upload with custom filename
43
superagent
44
.post('https://api.example.com/upload')
45
.attach('file', '/path/to/document.pdf', 'my-document.pdf');
46
47
// Upload with options object
48
superagent
49
.post('https://api.example.com/upload')
50
.attach('file', '/path/to/document.pdf', {
51
filename: 'custom-name.pdf',
52
contentType: 'application/pdf'
53
});
54
55
// Upload Buffer
56
const buffer = Buffer.from('Hello World');
57
superagent
58
.post('https://api.example.com/upload')
59
.attach('file', buffer, 'hello.txt');
60
61
// Upload Stream
62
const stream = fs.createReadStream('/path/to/large-file.zip');
63
superagent
64
.post('https://api.example.com/upload')
65
.attach('file', stream, 'archive.zip');
66
```
67
68
### Form Fields
69
70
Add non-file form fields to multipart requests.
71
72
```javascript
73
// Mixed form with file and fields
74
superagent
75
.post('https://api.example.com/upload')
76
.field('title', 'My Document')
77
.field('description', 'A sample document')
78
.field('category', 'documents')
79
.attach('file', '/path/to/document.pdf');
80
81
// Multiple values for same field
82
superagent
83
.post('https://api.example.com/upload')
84
.field('tags', 'document')
85
.field('tags', 'pdf')
86
.field('tags', 'important')
87
.attach('file', '/path/to/document.pdf');
88
```
89
90
### Multiple File Uploads
91
92
Upload multiple files in a single request.
93
94
```javascript
95
// Multiple files with different field names
96
superagent
97
.post('https://api.example.com/upload')
98
.attach('document', '/path/to/document.pdf')
99
.attach('image', '/path/to/image.jpg')
100
.attach('archive', '/path/to/data.zip');
101
102
// Multiple files with same field name
103
superagent
104
.post('https://api.example.com/upload')
105
.attach('files', '/path/to/file1.txt')
106
.attach('files', '/path/to/file2.txt')
107
.attach('files', '/path/to/file3.txt');
108
109
// Mixed upload with metadata
110
superagent
111
.post('https://api.example.com/upload')
112
.field('user_id', '12345')
113
.field('upload_type', 'batch')
114
.attach('files', '/path/to/file1.txt', 'first-file.txt')
115
.attach('files', '/path/to/file2.txt', 'second-file.txt');
116
```
117
118
### Dynamic File Uploads
119
120
Upload files with dynamic content or from various sources.
121
122
```javascript
123
// Upload from URL (download and upload)
124
const response = await superagent.get('https://example.com/remote-file.pdf');
125
superagent
126
.post('https://api.example.com/upload')
127
.attach('file', response.body, 'downloaded-file.pdf');
128
129
// Upload generated content
130
const csvData = 'name,age\nJohn,30\nJane,25';
131
const csvBuffer = Buffer.from(csvData);
132
superagent
133
.post('https://api.example.com/upload')
134
.attach('csv', csvBuffer, {
135
filename: 'data.csv',
136
contentType: 'text/csv'
137
});
138
139
// Upload with progress tracking
140
superagent
141
.post('https://api.example.com/upload')
142
.attach('file', '/path/to/large-file.zip')
143
.on('progress', (event) => {
144
console.log(`Upload progress: ${event.percent}%`);
145
console.log(`Loaded: ${event.loaded} / Total: ${event.total}`);
146
});
147
```
148
149
### Error Handling
150
151
Handle common file upload errors.
152
153
```javascript
154
// Upload with comprehensive error handling
155
superagent
156
.post('https://api.example.com/upload')
157
.attach('file', '/path/to/document.pdf')
158
.field('title', 'My Document')
159
.end((err, res) => {
160
if (err) {
161
if (err.code === 'ENOENT') {
162
console.error('File not found');
163
} else if (err.status === 413) {
164
console.error('File too large');
165
} else if (err.status === 415) {
166
console.error('Unsupported file type');
167
} else {
168
console.error('Upload failed:', err.message);
169
}
170
return;
171
}
172
173
console.log('Upload successful:', res.body);
174
});
175
176
// Promise-based error handling
177
try {
178
const response = await superagent
179
.post('https://api.example.com/upload')
180
.attach('file', '/path/to/document.pdf');
181
182
console.log('Upload successful:', response.body);
183
} catch (err) {
184
console.error('Upload failed:', err.message);
185
}
186
```
187
188
## Advanced Upload Patterns
189
190
### Chunked Upload
191
192
For large files, consider chunked upload patterns:
193
194
```javascript
195
const fs = require('fs');
196
const path = require('path');
197
198
async function uploadLargeFile(filePath, chunkSize = 1024 * 1024) {
199
const stats = fs.statSync(filePath);
200
const totalSize = stats.size;
201
let uploaded = 0;
202
203
// Initialize upload session
204
const session = await superagent
205
.post('https://api.example.com/upload/init')
206
.send({
207
filename: path.basename(filePath),
208
size: totalSize
209
});
210
211
const sessionId = session.body.sessionId;
212
213
// Upload chunks
214
while (uploaded < totalSize) {
215
const start = uploaded;
216
const end = Math.min(uploaded + chunkSize, totalSize);
217
const chunk = fs.createReadStream(filePath, { start, end: end - 1 });
218
219
await superagent
220
.post(`https://api.example.com/upload/chunk/${sessionId}`)
221
.attach('chunk', chunk)
222
.field('offset', start.toString())
223
.field('size', (end - start).toString());
224
225
uploaded = end;
226
console.log(`Uploaded: ${uploaded}/${totalSize} bytes`);
227
}
228
229
// Finalize upload
230
const result = await superagent
231
.post(`https://api.example.com/upload/finalize/${sessionId}`);
232
233
return result.body;
234
}
235
```
236
237
### Upload Validation
238
239
Validate files before uploading:
240
241
```javascript
242
const fs = require('fs');
243
const path = require('path');
244
245
function validateFile(filePath) {
246
const stats = fs.statSync(filePath);
247
const ext = path.extname(filePath).toLowerCase();
248
249
// Check file size (max 10MB)
250
if (stats.size > 10 * 1024 * 1024) {
251
throw new Error('File too large (max 10MB)');
252
}
253
254
// Check file type
255
const allowedTypes = ['.pdf', '.jpg', '.jpeg', '.png', '.doc', '.docx'];
256
if (!allowedTypes.includes(ext)) {
257
throw new Error('Unsupported file type');
258
}
259
260
return true;
261
}
262
263
// Usage
264
try {
265
validateFile('/path/to/document.pdf');
266
267
const response = await superagent
268
.post('https://api.example.com/upload')
269
.attach('file', '/path/to/document.pdf');
270
271
console.log('Upload successful');
272
} catch (err) {
273
console.error('Validation or upload failed:', err.message);
274
}
275
```
276
277
### Content Type Detection
278
279
Automatic and manual content type handling:
280
281
```javascript
282
// Automatic content type detection (based on file extension)
283
superagent
284
.post('https://api.example.com/upload')
285
.attach('file', '/path/to/image.jpg'); // Automatically sets image/jpeg
286
287
// Manual content type override
288
superagent
289
.post('https://api.example.com/upload')
290
.attach('file', '/path/to/data.bin', {
291
filename: 'data.json',
292
contentType: 'application/json'
293
});
294
295
// Content type for Buffers
296
const jsonData = JSON.stringify({ key: 'value' });
297
const buffer = Buffer.from(jsonData);
298
superagent
299
.post('https://api.example.com/upload')
300
.attach('data', buffer, {
301
filename: 'data.json',
302
contentType: 'application/json'
303
});
304
```