Readme.md (11857B)
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 3 A library to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications. 4 5 The 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/master.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/master.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/master.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/master.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 ``` 19 npm install --save form-data 20 ``` 21 22 ## Usage 23 24 In this example we are constructing a form with 3 fields that contain a string, 25 a buffer and a file stream. 26 27 ``` javascript 28 var FormData = require('form-data'); 29 var fs = require('fs'); 30 31 var form = new FormData(); 32 form.append('my_field', 'my value'); 33 form.append('my_buffer', new Buffer(10)); 34 form.append('my_file', fs.createReadStream('/foo/bar.jpg')); 35 ``` 36 37 Also you can use http-response stream: 38 39 ``` javascript 40 var FormData = require('form-data'); 41 var http = require('http'); 42 43 var form = new FormData(); 44 45 http.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 52 Or @mikeal's [request](https://github.com/request/request) stream: 53 54 ``` javascript 55 var FormData = require('form-data'); 56 var request = require('request'); 57 58 var form = new FormData(); 59 60 form.append('my_field', 'my value'); 61 form.append('my_buffer', new Buffer(10)); 62 form.append('my_logo', request('http://nodejs.org/images/logo.png')); 63 ``` 64 65 In order to submit this form to a web application, call ```submit(url, [callback])``` method: 66 67 ``` javascript 68 form.submit('http://example.org/', function(err, res) { 69 // res – response object (http.IncomingMessage) // 70 res.resume(); 71 }); 72 73 ``` 74 75 For 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 79 You can provide custom options, such as `maxDataSize`: 80 81 ``` javascript 82 var FormData = require('form-data'); 83 84 var form = new FormData({ maxDataSize: 20971520 }); 85 form.append('my_field', 'my value'); 86 form.append('my_buffer', /* something big */); 87 ``` 88 89 List 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 93 You can use node's http client interface: 94 95 ``` javascript 96 var http = require('http'); 97 98 var request = http.request({ 99 method: 'post', 100 host: 'example.org', 101 path: '/upload', 102 headers: form.getHeaders() 103 }); 104 105 form.pipe(request); 106 107 request.on('response', function(res) { 108 console.log(res.statusCode); 109 }); 110 ``` 111 112 Or if you would prefer the `'Content-Length'` header to be set for you: 113 114 ``` javascript 115 form.submit('example.org/upload', function(err, res) { 116 console.log(res.statusCode); 117 }); 118 ``` 119 120 To use custom headers and pre-known length in parts: 121 122 ``` javascript 123 var CRLF = '\r\n'; 124 var form = new FormData(); 125 126 var options = { 127 header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF, 128 knownLength: 1 129 }; 130 131 form.append('my_buffer', buffer, options); 132 133 form.submit('http://example.com/', function(err, res) { 134 if (err) throw err; 135 console.log('Done'); 136 }); 137 ``` 138 139 Form-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 142 someModule.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 161 The `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 163 For 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 166 form.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 175 In 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 178 form.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 - [_Buffer_ getBuffer()](https://github.com/form-data/form-data#buffer-getbuffer) 193 - [_Integer_ getLengthSync()](https://github.com/form-data/form-data#integer-getlengthsync) 194 - [_Integer_ getLength( **function** _callback_ )](https://github.com/form-data/form-data#integer-getlength-function-callback-) 195 - [_Boolean_ hasKnownLength()](https://github.com/form-data/form-data#boolean-hasknownlength) 196 - [_Request_ submit( _params_, **function** _callback_ )](https://github.com/form-data/form-data#request-submit-params-function-callback-) 197 - [_String_ toString()](https://github.com/form-data/form-data#string-tostring) 198 199 #### _Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] ) 200 Append 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. 201 ```javascript 202 var form = new FormData(); 203 form.append( 'my_string', 'my value' ); 204 form.append( 'my_integer', 1 ); 205 form.append( 'my_boolean', true ); 206 form.append( 'my_buffer', new Buffer(10) ); 207 form.append( 'my_array_as_json', JSON.stringify( ['bird','cute'] ) ) 208 ``` 209 210 You may provide a string for options, or an object. 211 ```javascript 212 // Set filename by providing a string for options 213 form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg' ); 214 215 // provide an object. 216 form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), {filename: 'bar.jpg', contentType: 'image/jpeg', knownLength: 19806} ); 217 ``` 218 219 #### _Headers_ getHeaders( [**Headers** _userHeaders_] ) 220 This method adds the correct `content-type` header to the provided array of `userHeaders`. 221 222 #### _String_ getBoundary() 223 Return the boundary of the formData. A boundary consists of 26 `-` followed by 24 numbers 224 for example: 225 ```javascript 226 --------------------------515890814546601021194782 227 ``` 228 _Note: The boundary must be unique and may not appear in the data._ 229 230 #### _Buffer_ getBuffer() 231 Return the full formdata request package, as a Buffer. You can insert this Buffer in e.g. Axios to send multipart data. 232 ```javascript 233 var form = new FormData(); 234 form.append( 'my_buffer', Buffer.from([0x4a,0x42,0x20,0x52,0x6f,0x63,0x6b,0x73]) ); 235 form.append( 'my_file', fs.readFileSync('/foo/bar.jpg') ); 236 237 axios.post( 'https://example.com/path/to/api', 238 form.getBuffer(), 239 form.getHeaders() 240 ) 241 ``` 242 **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. 243 244 #### _Integer_ getLengthSync() 245 Same as `getLength` but synchronous. 246 247 _Note: getLengthSync __doesn't__ calculate streams length._ 248 249 #### _Integer_ getLength( **function** _callback_ ) 250 Returns the `Content-Length` async. The callback is used to handle errors and continue once the length has been calculated 251 ```javascript 252 this.getLength(function(err, length) { 253 if (err) { 254 this._error(err); 255 return; 256 } 257 258 // add content length 259 request.setHeader('Content-Length', length); 260 261 ... 262 }.bind(this)); 263 ``` 264 265 #### _Boolean_ hasKnownLength() 266 Checks if the length of added values is known. 267 268 #### _Request_ submit( _params_, **function** _callback_ ) 269 Submit the form to a web application. 270 ```javascript 271 var form = new FormData(); 272 form.append( 'my_string', 'Hello World' ); 273 274 form.submit( 'http://example.com/', function(err, res) { 275 // res – response object (http.IncomingMessage) // 276 res.resume(); 277 } ); 278 ``` 279 280 #### _String_ toString() 281 Returns the form data as a string. Don't use this if you are sending files or buffers, use `getBuffer()` instead. 282 283 ### Integration with other libraries 284 285 #### Request 286 287 Form submission using [request](https://github.com/request/request): 288 289 ```javascript 290 var formData = { 291 my_field: 'my_value', 292 my_file: fs.createReadStream(__dirname + '/unicycle.jpg'), 293 }; 294 295 request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) { 296 if (err) { 297 return console.error('upload failed:', err); 298 } 299 console.log('Upload successful! Server responded with:', body); 300 }); 301 ``` 302 303 For more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads). 304 305 #### node-fetch 306 307 You can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch): 308 309 ```javascript 310 var form = new FormData(); 311 312 form.append('a', 1); 313 314 fetch('http://example.com', { method: 'POST', body: form }) 315 .then(function(res) { 316 return res.json(); 317 }).then(function(json) { 318 console.log(json); 319 }); 320 ``` 321 322 #### axios 323 324 In Node.js you can post a file using [axios](https://github.com/axios/axios): 325 ```javascript 326 const form = new FormData(); 327 const stream = fs.createReadStream(PATH_TO_FILE); 328 329 form.append('image', stream); 330 331 // In Node.js environment you need to set boundary in the header field 'Content-Type' by calling method `getHeaders` 332 const formHeaders = form.getHeaders(); 333 334 axios.post('http://example.com', form, { 335 headers: { 336 ...formHeaders, 337 }, 338 }) 339 .then(response => response) 340 .catch(error => error) 341 ``` 342 343 ## Notes 344 345 - ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround. 346 - ```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```). 347 - ```sbumit``` will not add `content-length` if form length is unknown or not calculable. 348 - Starting version `2.x` FormData has dropped support for `node@0.10.x`. 349 - Starting version `3.x` FormData has dropped support for `node@4.x`. 350 351 ## License 352 353 Form-Data is released under the [MIT](License) license.