UNPKG

12.1 kBMarkdownView Raw
1# Form-Data [![NPM Module](https://img.shields.io/npm/v/form-data.svg)](https://www.npmjs.com/package/form-data) [![Join the chat at https://gitter.im/form-data/form-data](http://form-data.github.io/images/gitterbadge.svg)](https://gitter.im/form-data/form-data)
2
3A library to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications.
4
5The API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd].
6
7[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface
8
9[![Linux Build](https://img.shields.io/travis/form-data/form-data/v4.0.0.svg?label=linux:6.x-12.x)](https://travis-ci.org/form-data/form-data)
10[![MacOS Build](https://img.shields.io/travis/form-data/form-data/v4.0.0.svg?label=macos:6.x-12.x)](https://travis-ci.org/form-data/form-data)
11[![Windows Build](https://img.shields.io/travis/form-data/form-data/v4.0.0.svg?label=windows:6.x-12.x)](https://travis-ci.org/form-data/form-data)
12
13[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/v4.0.0.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master)
14[![Dependency Status](https://img.shields.io/david/form-data/form-data.svg)](https://david-dm.org/form-data/form-data)
15
16## Install
17
18```
19npm install --save form-data
20```
21
22## Usage
23
24In this example we are constructing a form with 3 fields that contain a string,
25a buffer and a file stream.
26
27``` javascript
28var FormData = require('form-data');
29var fs = require('fs');
30
31var form = new FormData();
32form.append('my_field', 'my value');
33form.append('my_buffer', new Buffer(10));
34form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
35```
36
37Also you can use http-response stream:
38
39``` javascript
40var FormData = require('form-data');
41var http = require('http');
42
43var form = new FormData();
44
45http.request('http://nodejs.org/images/logo.png', function(response) {
46 form.append('my_field', 'my value');
47 form.append('my_buffer', new Buffer(10));
48 form.append('my_logo', response);
49});
50```
51
52Or @mikeal's [request](https://github.com/request/request) stream:
53
54``` javascript
55var FormData = require('form-data');
56var request = require('request');
57
58var form = new FormData();
59
60form.append('my_field', 'my value');
61form.append('my_buffer', new Buffer(10));
62form.append('my_logo', request('http://nodejs.org/images/logo.png'));
63```
64
65In order to submit this form to a web application, call ```submit(url, [callback])``` method:
66
67``` javascript
68form.submit('http://example.org/', function(err, res) {
69 // res – response object (http.IncomingMessage) //
70 res.resume();
71});
72
73```
74
75For more advanced request manipulations ```submit()``` method returns ```http.ClientRequest``` object, or you can choose from one of the alternative submission methods.
76
77### Custom options
78
79You can provide custom options, such as `maxDataSize`:
80
81``` javascript
82var FormData = require('form-data');
83
84var form = new FormData({ maxDataSize: 20971520 });
85form.append('my_field', 'my value');
86form.append('my_buffer', /* something big */);
87```
88
89List of available options could be found in [combined-stream](https://github.com/felixge/node-combined-stream/blob/master/lib/combined_stream.js#L7-L15)
90
91### Alternative submission methods
92
93You can use node's http client interface:
94
95``` javascript
96var http = require('http');
97
98var request = http.request({
99 method: 'post',
100 host: 'example.org',
101 path: '/upload',
102 headers: form.getHeaders()
103});
104
105form.pipe(request);
106
107request.on('response', function(res) {
108 console.log(res.statusCode);
109});
110```
111
112Or if you would prefer the `'Content-Length'` header to be set for you:
113
114``` javascript
115form.submit('example.org/upload', function(err, res) {
116 console.log(res.statusCode);
117});
118```
119
120To use custom headers and pre-known length in parts:
121
122``` javascript
123var CRLF = '\r\n';
124var form = new FormData();
125
126var options = {
127 header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,
128 knownLength: 1
129};
130
131form.append('my_buffer', buffer, options);
132
133form.submit('http://example.com/', function(err, res) {
134 if (err) throw err;
135 console.log('Done');
136});
137```
138
139Form-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide "file"-related information manually:
140
141``` javascript
142someModule.stream(function(err, stdout, stderr) {
143 if (err) throw err;
144
145 var form = new FormData();
146
147 form.append('file', stdout, {
148 filename: 'unicycle.jpg', // ... or:
149 filepath: 'photos/toys/unicycle.jpg',
150 contentType: 'image/jpeg',
151 knownLength: 19806
152 });
153
154 form.submit('http://example.com/', function(err, res) {
155 if (err) throw err;
156 console.log('Done');
157 });
158});
159```
160
161The `filepath` property overrides `filename` and may contain a relative path. This is typically used when uploading [multiple files from a directory](https://wicg.github.io/entries-api/#dom-htmlinputelement-webkitdirectory).
162
163For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter:
164
165``` javascript
166form.submit({
167 host: 'example.com',
168 path: '/probably.php?extra=params',
169 auth: 'username:password'
170}, function(err, res) {
171 console.log(res.statusCode);
172});
173```
174
175In case you need to also send custom HTTP headers with the POST request, you can use the `headers` key in first parameter of `form.submit()`:
176
177``` javascript
178form.submit({
179 host: 'example.com',
180 path: '/surelynot.php',
181 headers: {'x-test-header': 'test-header-value'}
182}, function(err, res) {
183 console.log(res.statusCode);
184});
185```
186
187### Methods
188
189- [_Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] )](https://github.com/form-data/form-data#void-append-string-field-mixed-value--mixed-options-).
190- [_Headers_ getHeaders( [**Headers** _userHeaders_] )](https://github.com/form-data/form-data#array-getheaders-array-userheaders-)
191- [_String_ getBoundary()](https://github.com/form-data/form-data#string-getboundary)
192- [_Void_ setBoundary()](https://github.com/form-data/form-data#void-setboundary)
193- [_Buffer_ getBuffer()](https://github.com/form-data/form-data#buffer-getbuffer)
194- [_Integer_ getLengthSync()](https://github.com/form-data/form-data#integer-getlengthsync)
195- [_Integer_ getLength( **function** _callback_ )](https://github.com/form-data/form-data#integer-getlength-function-callback-)
196- [_Boolean_ hasKnownLength()](https://github.com/form-data/form-data#boolean-hasknownlength)
197- [_Request_ submit( _params_, **function** _callback_ )](https://github.com/form-data/form-data#request-submit-params-function-callback-)
198- [_String_ toString()](https://github.com/form-data/form-data#string-tostring)
199
200#### _Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] )
201Append data to the form. You can submit about any format (string, integer, boolean, buffer, etc.). However, Arrays are not supported and need to be turned into strings by the user.
202```javascript
203var form = new FormData();
204form.append( 'my_string', 'my value' );
205form.append( 'my_integer', 1 );
206form.append( 'my_boolean', true );
207form.append( 'my_buffer', new Buffer(10) );
208form.append( 'my_array_as_json', JSON.stringify( ['bird','cute'] ) )
209```
210
211You may provide a string for options, or an object.
212```javascript
213// Set filename by providing a string for options
214form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg' );
215
216// provide an object.
217form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), {filename: 'bar.jpg', contentType: 'image/jpeg', knownLength: 19806} );
218```
219
220#### _Headers_ getHeaders( [**Headers** _userHeaders_] )
221This method adds the correct `content-type` header to the provided array of `userHeaders`.
222
223#### _String_ getBoundary()
224Return the boundary of the formData. By default, the boundary consists of 26 `-` followed by 24 numbers
225for example:
226```javascript
227--------------------------515890814546601021194782
228```
229
230#### _Void_ setBoundary(String _boundary_)
231Set the boundary string, overriding the default behavior described above.
232
233_Note: The boundary must be unique and may not appear in the data._
234
235#### _Buffer_ getBuffer()
236Return the full formdata request package, as a Buffer. You can insert this Buffer in e.g. Axios to send multipart data.
237```javascript
238var form = new FormData();
239form.append( 'my_buffer', Buffer.from([0x4a,0x42,0x20,0x52,0x6f,0x63,0x6b,0x73]) );
240form.append( 'my_file', fs.readFileSync('/foo/bar.jpg') );
241
242axios.post( 'https://example.com/path/to/api',
243 form.getBuffer(),
244 form.getHeaders()
245 )
246```
247**Note:** Because the output is of type Buffer, you can only append types that are accepted by Buffer: *string, Buffer, ArrayBuffer, Array, or Array-like Object*. A ReadStream for example will result in an error.
248
249#### _Integer_ getLengthSync()
250Same as `getLength` but synchronous.
251
252_Note: getLengthSync __doesn't__ calculate streams length._
253
254#### _Integer_ getLength( **function** _callback_ )
255Returns the `Content-Length` async. The callback is used to handle errors and continue once the length has been calculated
256```javascript
257this.getLength(function(err, length) {
258 if (err) {
259 this._error(err);
260 return;
261 }
262
263 // add content length
264 request.setHeader('Content-Length', length);
265
266 ...
267}.bind(this));
268```
269
270#### _Boolean_ hasKnownLength()
271Checks if the length of added values is known.
272
273#### _Request_ submit( _params_, **function** _callback_ )
274Submit the form to a web application.
275```javascript
276var form = new FormData();
277form.append( 'my_string', 'Hello World' );
278
279form.submit( 'http://example.com/', function(err, res) {
280 // res – response object (http.IncomingMessage) //
281 res.resume();
282} );
283```
284
285#### _String_ toString()
286Returns the form data as a string. Don't use this if you are sending files or buffers, use `getBuffer()` instead.
287
288### Integration with other libraries
289
290#### Request
291
292Form submission using [request](https://github.com/request/request):
293
294```javascript
295var formData = {
296 my_field: 'my_value',
297 my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
298};
299
300request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) {
301 if (err) {
302 return console.error('upload failed:', err);
303 }
304 console.log('Upload successful! Server responded with:', body);
305});
306```
307
308For more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads).
309
310#### node-fetch
311
312You can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch):
313
314```javascript
315var form = new FormData();
316
317form.append('a', 1);
318
319fetch('http://example.com', { method: 'POST', body: form })
320 .then(function(res) {
321 return res.json();
322 }).then(function(json) {
323 console.log(json);
324 });
325```
326
327#### axios
328
329In Node.js you can post a file using [axios](https://github.com/axios/axios):
330```javascript
331const form = new FormData();
332const stream = fs.createReadStream(PATH_TO_FILE);
333
334form.append('image', stream);
335
336// In Node.js environment you need to set boundary in the header field 'Content-Type' by calling method `getHeaders`
337const formHeaders = form.getHeaders();
338
339axios.post('http://example.com', form, {
340 headers: {
341 ...formHeaders,
342 },
343})
344.then(response => response)
345.catch(error => error)
346```
347
348## Notes
349
350- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround.
351- ```getLength(cb)``` will send an error as first parameter of callback if stream length cannot be calculated (e.g. send in custom streams w/o using ```knownLength```).
352- ```submit``` will not add `content-length` if form length is unknown or not calculable.
353- Starting version `2.x` FormData has dropped support for `node@0.10.x`.
354- Starting version `3.x` FormData has dropped support for `node@4.x`.
355
356## License
357
358Form-Data is released under the [MIT](License) license.
359
\No newline at end of file