UNPKG

44.5 kBMarkdownView Raw
1
2# Request - Simplified HTTP client
3
4[![npm package](https://nodei.co/npm/request.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/request/)
5
6[![Build status](https://img.shields.io/travis/request/request/master.svg?style=flat-square)](https://travis-ci.org/request/request)
7[![Coverage](https://img.shields.io/codecov/c/github/request/request.svg?style=flat-square)](https://codecov.io/github/request/request?branch=master)
8[![Coverage](https://img.shields.io/coveralls/request/request.svg?style=flat-square)](https://coveralls.io/r/request/request)
9[![Dependency Status](https://img.shields.io/david/request/request.svg?style=flat-square)](https://david-dm.org/request/request)
10[![Known Vulnerabilities](https://snyk.io/test/npm/request/badge.svg?style=flat-square)](https://snyk.io/test/npm/request)
11[![Gitter](https://img.shields.io/badge/gitter-join_chat-blue.svg?style=flat-square)](https://gitter.im/request/request?utm_source=badge)
12
13
14## Super simple to use
15
16Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.
17
18```js
19var request = require('request');
20request('http://www.google.com', function (error, response, body) {
21 console.log('error:', error); // Print the error if one occurred
22 console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
23 console.log('body:', body); // Print the HTML for the Google homepage.
24});
25```
26
27
28## Table of contents
29
30- [Streaming](#streaming)
31- [Promises & Async/Await](#promises--asyncawait)
32- [Forms](#forms)
33- [HTTP Authentication](#http-authentication)
34- [Custom HTTP Headers](#custom-http-headers)
35- [OAuth Signing](#oauth-signing)
36- [Proxies](#proxies)
37- [Unix Domain Sockets](#unix-domain-sockets)
38- [TLS/SSL Protocol](#tlsssl-protocol)
39- [Support for HAR 1.2](#support-for-har-12)
40- [**All Available Options**](#requestoptions-callback)
41
42Request also offers [convenience methods](#convenience-methods) like
43`request.defaults` and `request.post`, and there are
44lots of [usage examples](#examples) and several
45[debugging techniques](#debugging).
46
47
48---
49
50
51## Streaming
52
53You can stream any response to a file stream.
54
55```js
56request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))
57```
58
59You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types (in this case `application/json`) and use the proper `content-type` in the PUT request (if the headers don’t already provide one).
60
61```js
62fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))
63```
64
65Request can also `pipe` to itself. When doing so, `content-type` and `content-length` are preserved in the PUT headers.
66
67```js
68request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))
69```
70
71Request emits a "response" event when a response is received. The `response` argument will be an instance of [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage).
72
73```js
74request
75 .get('http://google.com/img.png')
76 .on('response', function(response) {
77 console.log(response.statusCode) // 200
78 console.log(response.headers['content-type']) // 'image/png'
79 })
80 .pipe(request.put('http://mysite.com/img.png'))
81```
82
83To easily handle errors when streaming requests, listen to the `error` event before piping:
84
85```js
86request
87 .get('http://mysite.com/doodle.png')
88 .on('error', function(err) {
89 console.log(err)
90 })
91 .pipe(fs.createWriteStream('doodle.png'))
92```
93
94Now let’s get fancy.
95
96```js
97http.createServer(function (req, resp) {
98 if (req.url === '/doodle.png') {
99 if (req.method === 'PUT') {
100 req.pipe(request.put('http://mysite.com/doodle.png'))
101 } else if (req.method === 'GET' || req.method === 'HEAD') {
102 request.get('http://mysite.com/doodle.png').pipe(resp)
103 }
104 }
105})
106```
107
108You can also `pipe()` from `http.ServerRequest` instances, as well as to `http.ServerResponse` instances. The HTTP method, headers, and entity-body data will be sent. Which means that, if you don't really care about security, you can do:
109
110```js
111http.createServer(function (req, resp) {
112 if (req.url === '/doodle.png') {
113 var x = request('http://mysite.com/doodle.png')
114 req.pipe(x)
115 x.pipe(resp)
116 }
117})
118```
119
120And since `pipe()` returns the destination stream in ≥ Node 0.5.x you can do one line proxying. :)
121
122```js
123req.pipe(request('http://mysite.com/doodle.png')).pipe(resp)
124```
125
126Also, none of this new functionality conflicts with requests previous features, it just expands them.
127
128```js
129var r = request.defaults({'proxy':'http://localproxy.com'})
130
131http.createServer(function (req, resp) {
132 if (req.url === '/doodle.png') {
133 r.get('http://google.com/doodle.png').pipe(resp)
134 }
135})
136```
137
138You can still use intermediate proxies, the requests will still follow HTTP forwards, etc.
139
140[back to top](#table-of-contents)
141
142
143---
144
145
146## Promises & Async/Await
147
148`request` supports both streaming and callback interfaces natively. If you'd like `request` to return a Promise instead, you can use an alternative interface wrapper for `request`. These wrappers can be useful if you prefer to work with Promises, or if you'd like to use `async`/`await` in ES2017.
149
150Several alternative interfaces are provided by the request team, including:
151- [`request-promise`](https://github.com/request/request-promise) (uses [Bluebird](https://github.com/petkaantonov/bluebird) Promises)
152- [`request-promise-native`](https://github.com/request/request-promise-native) (uses native Promises)
153- [`request-promise-any`](https://github.com/request/request-promise-any) (uses [any-promise](https://www.npmjs.com/package/any-promise) Promises)
154
155
156[back to top](#table-of-contents)
157
158
159---
160
161
162## Forms
163
164`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API.
165
166
167#### application/x-www-form-urlencoded (URL-Encoded Forms)
168
169URL-encoded forms are simple.
170
171```js
172request.post('http://service.com/upload', {form:{key:'value'}})
173// or
174request.post('http://service.com/upload').form({key:'value'})
175// or
176request.post({url:'http://service.com/upload', form: {key:'value'}}, function(err,httpResponse,body){ /* ... */ })
177```
178
179
180#### multipart/form-data (Multipart Form Uploads)
181
182For `multipart/form-data` we use the [form-data](https://github.com/form-data/form-data) library by [@felixge](https://github.com/felixge). For the most cases, you can pass your upload form data via the `formData` option.
183
184
185```js
186var formData = {
187 // Pass a simple key-value pair
188 my_field: 'my_value',
189 // Pass data via Buffers
190 my_buffer: Buffer.from([1, 2, 3]),
191 // Pass data via Streams
192 my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
193 // Pass multiple values /w an Array
194 attachments: [
195 fs.createReadStream(__dirname + '/attachment1.jpg'),
196 fs.createReadStream(__dirname + '/attachment2.jpg')
197 ],
198 // Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
199 // Use case: for some types of streams, you'll need to provide "file"-related information manually.
200 // See the `form-data` README for more information about options: https://github.com/form-data/form-data
201 custom_file: {
202 value: fs.createReadStream('/dev/urandom'),
203 options: {
204 filename: 'topsecret.jpg',
205 contentType: 'image/jpeg'
206 }
207 }
208};
209request.post({url:'http://service.com/upload', formData: formData}, function optionalCallback(err, httpResponse, body) {
210 if (err) {
211 return console.error('upload failed:', err);
212 }
213 console.log('Upload successful! Server responded with:', body);
214});
215```
216
217For advanced cases, you can access the form-data object itself via `r.form()`. This can be modified until the request is fired on the next cycle of the event-loop. (Note that this calling `form()` will clear the currently set form data for that request.)
218
219```js
220// NOTE: Advanced use-case, for normal use see 'formData' usage above
221var r = request.post('http://service.com/upload', function optionalCallback(err, httpResponse, body) {...})
222var form = r.form();
223form.append('my_field', 'my_value');
224form.append('my_buffer', Buffer.from([1, 2, 3]));
225form.append('custom_file', fs.createReadStream(__dirname + '/unicycle.jpg'), {filename: 'unicycle.jpg'});
226```
227See the [form-data README](https://github.com/form-data/form-data) for more information & examples.
228
229
230#### multipart/related
231
232Some variations in different HTTP implementations require a newline/CRLF before, after, or both before and after the boundary of a `multipart/related` request (using the multipart option). This has been observed in the .NET WebAPI version 4.0. You can turn on a boundary preambleCRLF or postamble by passing them as `true` to your request options.
233
234```js
235 request({
236 method: 'PUT',
237 preambleCRLF: true,
238 postambleCRLF: true,
239 uri: 'http://service.com/upload',
240 multipart: [
241 {
242 'content-type': 'application/json',
243 body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
244 },
245 { body: 'I am an attachment' },
246 { body: fs.createReadStream('image.png') }
247 ],
248 // alternatively pass an object containing additional options
249 multipart: {
250 chunked: false,
251 data: [
252 {
253 'content-type': 'application/json',
254 body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
255 },
256 { body: 'I am an attachment' }
257 ]
258 }
259 },
260 function (error, response, body) {
261 if (error) {
262 return console.error('upload failed:', error);
263 }
264 console.log('Upload successful! Server responded with:', body);
265 })
266```
267
268[back to top](#table-of-contents)
269
270
271---
272
273
274## HTTP Authentication
275
276```js
277request.get('http://some.server.com/').auth('username', 'password', false);
278// or
279request.get('http://some.server.com/', {
280 'auth': {
281 'user': 'username',
282 'pass': 'password',
283 'sendImmediately': false
284 }
285});
286// or
287request.get('http://some.server.com/').auth(null, null, true, 'bearerToken');
288// or
289request.get('http://some.server.com/', {
290 'auth': {
291 'bearer': 'bearerToken'
292 }
293});
294```
295
296If passed as an option, `auth` should be a hash containing values:
297
298- `user` || `username`
299- `pass` || `password`
300- `sendImmediately` (optional)
301- `bearer` (optional)
302
303The method form takes parameters
304`auth(username, password, sendImmediately, bearer)`.
305
306`sendImmediately` defaults to `true`, which causes a basic or bearer
307authentication header to be sent. If `sendImmediately` is `false`, then
308`request` will retry with a proper authentication header after receiving a
309`401` response from the server (which must contain a `WWW-Authenticate` header
310indicating the required authentication method).
311
312Note that you can also specify basic authentication using the URL itself, as
313detailed in [RFC 1738](http://www.ietf.org/rfc/rfc1738.txt). Simply pass the
314`user:password` before the host with an `@` sign:
315
316```js
317var username = 'username',
318 password = 'password',
319 url = 'http://' + username + ':' + password + '@some.server.com';
320
321request({url: url}, function (error, response, body) {
322 // Do more stuff with 'body' here
323});
324```
325
326Digest authentication is supported, but it only works with `sendImmediately`
327set to `false`; otherwise `request` will send basic authentication on the
328initial request, which will probably cause the request to fail.
329
330Bearer authentication is supported, and is activated when the `bearer` value is
331available. The value may be either a `String` or a `Function` returning a
332`String`. Using a function to supply the bearer token is particularly useful if
333used in conjunction with `defaults` to allow a single function to supply the
334last known token at the time of sending a request, or to compute one on the fly.
335
336[back to top](#table-of-contents)
337
338
339---
340
341
342## Custom HTTP Headers
343
344HTTP Headers, such as `User-Agent`, can be set in the `options` object.
345In the example below, we call the github API to find out the number
346of stars and forks for the request repository. This requires a
347custom `User-Agent` header as well as https.
348
349```js
350var request = require('request');
351
352var options = {
353 url: 'https://api.github.com/repos/request/request',
354 headers: {
355 'User-Agent': 'request'
356 }
357};
358
359function callback(error, response, body) {
360 if (!error && response.statusCode == 200) {
361 var info = JSON.parse(body);
362 console.log(info.stargazers_count + " Stars");
363 console.log(info.forks_count + " Forks");
364 }
365}
366
367request(options, callback);
368```
369
370[back to top](#table-of-contents)
371
372
373---
374
375
376## OAuth Signing
377
378[OAuth version 1.0](https://tools.ietf.org/html/rfc5849) is supported. The
379default signing algorithm is
380[HMAC-SHA1](https://tools.ietf.org/html/rfc5849#section-3.4.2):
381
382```js
383// OAuth1.0 - 3-legged server side flow (Twitter example)
384// step 1
385var qs = require('querystring')
386 , oauth =
387 { callback: 'http://mysite.com/callback/'
388 , consumer_key: CONSUMER_KEY
389 , consumer_secret: CONSUMER_SECRET
390 }
391 , url = 'https://api.twitter.com/oauth/request_token'
392 ;
393request.post({url:url, oauth:oauth}, function (e, r, body) {
394 // Ideally, you would take the body in the response
395 // and construct a URL that a user clicks on (like a sign in button).
396 // The verifier is only available in the response after a user has
397 // verified with twitter that they are authorizing your app.
398
399 // step 2
400 var req_data = qs.parse(body)
401 var uri = 'https://api.twitter.com/oauth/authenticate'
402 + '?' + qs.stringify({oauth_token: req_data.oauth_token})
403 // redirect the user to the authorize uri
404
405 // step 3
406 // after the user is redirected back to your server
407 var auth_data = qs.parse(body)
408 , oauth =
409 { consumer_key: CONSUMER_KEY
410 , consumer_secret: CONSUMER_SECRET
411 , token: auth_data.oauth_token
412 , token_secret: req_data.oauth_token_secret
413 , verifier: auth_data.oauth_verifier
414 }
415 , url = 'https://api.twitter.com/oauth/access_token'
416 ;
417 request.post({url:url, oauth:oauth}, function (e, r, body) {
418 // ready to make signed requests on behalf of the user
419 var perm_data = qs.parse(body)
420 , oauth =
421 { consumer_key: CONSUMER_KEY
422 , consumer_secret: CONSUMER_SECRET
423 , token: perm_data.oauth_token
424 , token_secret: perm_data.oauth_token_secret
425 }
426 , url = 'https://api.twitter.com/1.1/users/show.json'
427 , qs =
428 { screen_name: perm_data.screen_name
429 , user_id: perm_data.user_id
430 }
431 ;
432 request.get({url:url, oauth:oauth, qs:qs, json:true}, function (e, r, user) {
433 console.log(user)
434 })
435 })
436})
437```
438
439For [RSA-SHA1 signing](https://tools.ietf.org/html/rfc5849#section-3.4.3), make
440the following changes to the OAuth options object:
441* Pass `signature_method : 'RSA-SHA1'`
442* Instead of `consumer_secret`, specify a `private_key` string in
443 [PEM format](http://how2ssl.com/articles/working_with_pem_files/)
444
445For [PLAINTEXT signing](http://oauth.net/core/1.0/#anchor22), make
446the following changes to the OAuth options object:
447* Pass `signature_method : 'PLAINTEXT'`
448
449To send OAuth parameters via query params or in a post body as described in The
450[Consumer Request Parameters](http://oauth.net/core/1.0/#consumer_req_param)
451section of the oauth1 spec:
452* Pass `transport_method : 'query'` or `transport_method : 'body'` in the OAuth
453 options object.
454* `transport_method` defaults to `'header'`
455
456To use [Request Body Hash](https://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html) you can either
457* Manually generate the body hash and pass it as a string `body_hash: '...'`
458* Automatically generate the body hash by passing `body_hash: true`
459
460[back to top](#table-of-contents)
461
462
463---
464
465
466## Proxies
467
468If you specify a `proxy` option, then the request (and any subsequent
469redirects) will be sent via a connection to the proxy server.
470
471If your endpoint is an `https` url, and you are using a proxy, then
472request will send a `CONNECT` request to the proxy server *first*, and
473then use the supplied connection to connect to the endpoint.
474
475That is, first it will make a request like:
476
477```
478HTTP/1.1 CONNECT endpoint-server.com:80
479Host: proxy-server.com
480User-Agent: whatever user agent you specify
481```
482
483and then the proxy server make a TCP connection to `endpoint-server`
484on port `80`, and return a response that looks like:
485
486```
487HTTP/1.1 200 OK
488```
489
490At this point, the connection is left open, and the client is
491communicating directly with the `endpoint-server.com` machine.
492
493See [the wikipedia page on HTTP Tunneling](https://en.wikipedia.org/wiki/HTTP_tunnel)
494for more information.
495
496By default, when proxying `http` traffic, request will simply make a
497standard proxied `http` request. This is done by making the `url`
498section of the initial line of the request a fully qualified url to
499the endpoint.
500
501For example, it will make a single request that looks like:
502
503```
504HTTP/1.1 GET http://endpoint-server.com/some-url
505Host: proxy-server.com
506Other-Headers: all go here
507
508request body or whatever
509```
510
511Because a pure "http over http" tunnel offers no additional security
512or other features, it is generally simpler to go with a
513straightforward HTTP proxy in this case. However, if you would like
514to force a tunneling proxy, you may set the `tunnel` option to `true`.
515
516You can also make a standard proxied `http` request by explicitly setting
517`tunnel : false`, but **note that this will allow the proxy to see the traffic
518to/from the destination server**.
519
520If you are using a tunneling proxy, you may set the
521`proxyHeaderWhiteList` to share certain headers with the proxy.
522
523You can also set the `proxyHeaderExclusiveList` to share certain
524headers only with the proxy and not with destination host.
525
526By default, this set is:
527
528```
529accept
530accept-charset
531accept-encoding
532accept-language
533accept-ranges
534cache-control
535content-encoding
536content-language
537content-length
538content-location
539content-md5
540content-range
541content-type
542connection
543date
544expect
545max-forwards
546pragma
547proxy-authorization
548referer
549te
550transfer-encoding
551user-agent
552via
553```
554
555Note that, when using a tunneling proxy, the `proxy-authorization`
556header and any headers from custom `proxyHeaderExclusiveList` are
557*never* sent to the endpoint server, but only to the proxy server.
558
559
560### Controlling proxy behaviour using environment variables
561
562The following environment variables are respected by `request`:
563
564 * `HTTP_PROXY` / `http_proxy`
565 * `HTTPS_PROXY` / `https_proxy`
566 * `NO_PROXY` / `no_proxy`
567
568When `HTTP_PROXY` / `http_proxy` are set, they will be used to proxy non-SSL requests that do not have an explicit `proxy` configuration option present. Similarly, `HTTPS_PROXY` / `https_proxy` will be respected for SSL requests that do not have an explicit `proxy` configuration option. It is valid to define a proxy in one of the environment variables, but then override it for a specific request, using the `proxy` configuration option. Furthermore, the `proxy` configuration option can be explicitly set to false / null to opt out of proxying altogether for that request.
569
570`request` is also aware of the `NO_PROXY`/`no_proxy` environment variables. These variables provide a granular way to opt out of proxying, on a per-host basis. It should contain a comma separated list of hosts to opt out of proxying. It is also possible to opt of proxying when a particular destination port is used. Finally, the variable may be set to `*` to opt out of the implicit proxy configuration of the other environment variables.
571
572Here's some examples of valid `no_proxy` values:
573
574 * `google.com` - don't proxy HTTP/HTTPS requests to Google.
575 * `google.com:443` - don't proxy HTTPS requests to Google, but *do* proxy HTTP requests to Google.
576 * `google.com:443, yahoo.com:80` - don't proxy HTTPS requests to Google, and don't proxy HTTP requests to Yahoo!
577 * `*` - ignore `https_proxy`/`http_proxy` environment variables altogether.
578
579[back to top](#table-of-contents)
580
581
582---
583
584
585## UNIX Domain Sockets
586
587`request` supports making requests to [UNIX Domain Sockets](https://en.wikipedia.org/wiki/Unix_domain_socket). To make one, use the following URL scheme:
588
589```js
590/* Pattern */ 'http://unix:SOCKET:PATH'
591/* Example */ request.get('http://unix:/absolute/path/to/unix.socket:/request/path')
592```
593
594Note: The `SOCKET` path is assumed to be absolute to the root of the host file system.
595
596[back to top](#table-of-contents)
597
598
599---
600
601
602## TLS/SSL Protocol
603
604TLS/SSL Protocol options, such as `cert`, `key` and `passphrase`, can be
605set directly in `options` object, in the `agentOptions` property of the `options` object, or even in `https.globalAgent.options`. Keep in mind that, although `agentOptions` allows for a slightly wider range of configurations, the recommended way is via `options` object directly, as using `agentOptions` or `https.globalAgent.options` would not be applied in the same way in proxied environments (as data travels through a TLS connection instead of an http/https agent).
606
607```js
608var fs = require('fs')
609 , path = require('path')
610 , certFile = path.resolve(__dirname, 'ssl/client.crt')
611 , keyFile = path.resolve(__dirname, 'ssl/client.key')
612 , caFile = path.resolve(__dirname, 'ssl/ca.cert.pem')
613 , request = require('request');
614
615var options = {
616 url: 'https://api.some-server.com/',
617 cert: fs.readFileSync(certFile),
618 key: fs.readFileSync(keyFile),
619 passphrase: 'password',
620 ca: fs.readFileSync(caFile)
621};
622
623request.get(options);
624```
625
626### Using `options.agentOptions`
627
628In the example below, we call an API that requires client side SSL certificate
629(in PEM format) with passphrase protected private key (in PEM format) and disable the SSLv3 protocol:
630
631```js
632var fs = require('fs')
633 , path = require('path')
634 , certFile = path.resolve(__dirname, 'ssl/client.crt')
635 , keyFile = path.resolve(__dirname, 'ssl/client.key')
636 , request = require('request');
637
638var options = {
639 url: 'https://api.some-server.com/',
640 agentOptions: {
641 cert: fs.readFileSync(certFile),
642 key: fs.readFileSync(keyFile),
643 // Or use `pfx` property replacing `cert` and `key` when using private key, certificate and CA certs in PFX or PKCS12 format:
644 // pfx: fs.readFileSync(pfxFilePath),
645 passphrase: 'password',
646 securityOptions: 'SSL_OP_NO_SSLv3'
647 }
648};
649
650request.get(options);
651```
652
653It is able to force using SSLv3 only by specifying `secureProtocol`:
654
655```js
656request.get({
657 url: 'https://api.some-server.com/',
658 agentOptions: {
659 secureProtocol: 'SSLv3_method'
660 }
661});
662```
663
664It is possible to accept other certificates than those signed by generally allowed Certificate Authorities (CAs).
665This can be useful, for example, when using self-signed certificates.
666To require a different root certificate, you can specify the signing CA by adding the contents of the CA's certificate file to the `agentOptions`.
667The certificate the domain presents must be signed by the root certificate specified:
668
669```js
670request.get({
671 url: 'https://api.some-server.com/',
672 agentOptions: {
673 ca: fs.readFileSync('ca.cert.pem')
674 }
675});
676```
677
678[back to top](#table-of-contents)
679
680
681---
682
683## Support for HAR 1.2
684
685The `options.har` property will override the values: `url`, `method`, `qs`, `headers`, `form`, `formData`, `body`, `json`, as well as construct multipart data and read files from disk when `request.postData.params[].fileName` is present without a matching `value`.
686
687A validation step will check if the HAR Request format matches the latest spec (v1.2) and will skip parsing if not matching.
688
689```js
690 var request = require('request')
691 request({
692 // will be ignored
693 method: 'GET',
694 uri: 'http://www.google.com',
695
696 // HTTP Archive Request Object
697 har: {
698 url: 'http://www.mockbin.com/har',
699 method: 'POST',
700 headers: [
701 {
702 name: 'content-type',
703 value: 'application/x-www-form-urlencoded'
704 }
705 ],
706 postData: {
707 mimeType: 'application/x-www-form-urlencoded',
708 params: [
709 {
710 name: 'foo',
711 value: 'bar'
712 },
713 {
714 name: 'hello',
715 value: 'world'
716 }
717 ]
718 }
719 }
720 })
721
722 // a POST request will be sent to http://www.mockbin.com
723 // with body an application/x-www-form-urlencoded body:
724 // foo=bar&hello=world
725```
726
727[back to top](#table-of-contents)
728
729
730---
731
732## request(options, callback)
733
734The first argument can be either a `url` or an `options` object. The only required option is `uri`; all others are optional.
735
736- `uri` || `url` - fully qualified uri or a parsed url object from `url.parse()`
737- `baseUrl` - fully qualified uri string used as the base url. Most useful with `request.defaults`, for example when you want to do many requests to the same domain. If `baseUrl` is `https://example.com/api/`, then requesting `/end/point?test=true` will fetch `https://example.com/api/end/point?test=true`. When `baseUrl` is given, `uri` must also be a string.
738- `method` - http method (default: `"GET"`)
739- `headers` - http headers (default: `{}`)
740
741---
742
743- `qs` - object containing querystring values to be appended to the `uri`
744- `qsParseOptions` - object containing options to pass to the [qs.parse](https://github.com/hapijs/qs#parsing-objects) method. Alternatively pass options to the [querystring.parse](https://nodejs.org/docs/v0.12.0/api/querystring.html#querystring_querystring_parse_str_sep_eq_options) method using this format `{sep:';', eq:':', options:{}}`
745- `qsStringifyOptions` - object containing options to pass to the [qs.stringify](https://github.com/hapijs/qs#stringifying) method. Alternatively pass options to the [querystring.stringify](https://nodejs.org/docs/v0.12.0/api/querystring.html#querystring_querystring_stringify_obj_sep_eq_options) method using this format `{sep:';', eq:':', options:{}}`. For example, to change the way arrays are converted to query strings using the `qs` module pass the `arrayFormat` option with one of `indices|brackets|repeat`
746- `useQuerystring` - if true, use `querystring` to stringify and parse
747 querystrings, otherwise use `qs` (default: `false`). Set this option to
748 `true` if you need arrays to be serialized as `foo=bar&foo=baz` instead of the
749 default `foo[0]=bar&foo[1]=baz`.
750
751---
752
753- `body` - entity body for PATCH, POST and PUT requests. Must be a `Buffer`, `String` or `ReadStream`. If `json` is `true`, then `body` must be a JSON-serializable object.
754- `form` - when passed an object or a querystring, this sets `body` to a querystring representation of value, and adds `Content-type: application/x-www-form-urlencoded` header. When passed no options, a `FormData` instance is returned (and is piped to request). See "Forms" section above.
755- `formData` - data to pass for a `multipart/form-data` request. See
756 [Forms](#forms) section above.
757- `multipart` - array of objects which contain their own headers and `body`
758 attributes. Sends a `multipart/related` request. See [Forms](#forms) section
759 above.
760 - Alternatively you can pass in an object `{chunked: false, data: []}` where
761 `chunked` is used to specify whether the request is sent in
762 [chunked transfer encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding)
763 In non-chunked requests, data items with body streams are not allowed.
764- `preambleCRLF` - append a newline/CRLF before the boundary of your `multipart/form-data` request.
765- `postambleCRLF` - append a newline/CRLF at the end of the boundary of your `multipart/form-data` request.
766- `json` - sets `body` to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as JSON.
767- `jsonReviver` - a [reviver function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) that will be passed to `JSON.parse()` when parsing a JSON response body.
768- `jsonReplacer` - a [replacer function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that will be passed to `JSON.stringify()` when stringifying a JSON request body.
769
770---
771
772- `auth` - a hash containing values `user` || `username`, `pass` || `password`, and `sendImmediately` (optional). See documentation above.
773- `oauth` - options for OAuth HMAC-SHA1 signing. See documentation above.
774- `hawk` - options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example).
775- `aws` - `object` containing AWS signing information. Should have the properties `key`, `secret`, and optionally `session` (note that this only works for services that require session as part of the canonical string). Also requires the property `bucket`, unless you’re specifying your `bucket` as part of the path, or the request doesn’t use a bucket (i.e. GET Services). If you want to use AWS sign version 4 use the parameter `sign_version` with value `4` otherwise the default is version 2. **Note:** you need to `npm install aws4` first.
776- `httpSignature` - options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options.
777
778---
779
780- `followRedirect` - follow HTTP 3xx responses as redirects (default: `true`). This property can also be implemented as function which gets `response` object as a single argument and should return `true` if redirects should continue or `false` otherwise.
781- `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects (default: `false`)
782- `followOriginalHttpMethod` - by default we redirect to HTTP method GET. you can enable this property to redirect to the original HTTP method (default: `false`)
783- `maxRedirects` - the maximum number of redirects to follow (default: `10`)
784- `removeRefererHeader` - removes the referer header when a redirect happens (default: `false`). **Note:** if true, referer header set in the initial request is preserved during redirect chain.
785
786---
787
788- `encoding` - encoding to be used on `setEncoding` of response data. If `null`, the `body` is returned as a `Buffer`. Anything else **(including the default value of `undefined`)** will be passed as the [encoding](http://nodejs.org/api/buffer.html#buffer_buffer) parameter to `toString()` (meaning this is effectively `utf8` by default). (**Note:** if you expect binary data, you should set `encoding: null`.)
789- `gzip` - if `true`, add an `Accept-Encoding` header to request compressed content encodings from the server (if not already present) and decode supported content encodings in the response. **Note:** Automatic decoding of the response content is performed on the body data returned through `request` (both through the `request` stream and passed to the callback function) but is not performed on the `response` stream (available from the `response` event) which is the unmodified `http.IncomingMessage` object which may contain compressed data. See example below.
790- `jar` - if `true`, remember cookies for future use (or define your custom cookie jar; see examples section)
791
792---
793
794- `agent` - `http(s).Agent` instance to use
795- `agentClass` - alternatively specify your agent's class name
796- `agentOptions` - and pass its options. **Note:** for HTTPS see [tls API doc for TLS/SSL options](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback) and the [documentation above](#using-optionsagentoptions).
797- `forever` - set to `true` to use the [forever-agent](https://github.com/request/forever-agent) **Note:** Defaults to `http(s).Agent({keepAlive:true})` in node 0.12+
798- `pool` - an object describing which agents to use for the request. If this option is omitted the request will use the global agent (as long as your options allow for it). Otherwise, request will search the pool for your custom agent. If no custom agent is found, a new agent will be created and added to the pool. **Note:** `pool` is used only when the `agent` option is not specified.
799 - A `maxSockets` property can also be provided on the `pool` object to set the max number of sockets for all agents created (ex: `pool: {maxSockets: Infinity}`).
800 - Note that if you are sending multiple requests in a loop and creating
801 multiple new `pool` objects, `maxSockets` will not work as intended. To
802 work around this, either use [`request.defaults`](#requestdefaultsoptions)
803 with your pool options or create the pool object with the `maxSockets`
804 property outside of the loop.
805- `timeout` - integer containing the number of milliseconds to wait for a
806server to send response headers (and start the response body) before aborting
807the request. Note that if the underlying TCP connection cannot be established,
808the OS-wide TCP connection timeout will overrule the `timeout` option ([the
809default in Linux can be anywhere from 20-120 seconds][linux-timeout]).
810
811[linux-timeout]: http://www.sekuda.com/overriding_the_default_linux_kernel_20_second_tcp_socket_connect_timeout
812
813---
814
815- `localAddress` - local interface to bind for network connections.
816- `proxy` - an HTTP proxy to be used. Supports proxy Auth with Basic Auth, identical to support for the `url` parameter (by embedding the auth info in the `uri`)
817- `strictSSL` - if `true`, requires SSL certificates be valid. **Note:** to use your own certificate authority, you need to specify an agent that was created with that CA as an option.
818- `tunnel` - controls the behavior of
819 [HTTP `CONNECT` tunneling](https://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_tunneling)
820 as follows:
821 - `undefined` (default) - `true` if the destination is `https`, `false` otherwise
822 - `true` - always tunnel to the destination by making a `CONNECT` request to
823 the proxy
824 - `false` - request the destination as a `GET` request.
825- `proxyHeaderWhiteList` - a whitelist of headers to send to a
826 tunneling proxy.
827- `proxyHeaderExclusiveList` - a whitelist of headers to send
828 exclusively to a tunneling proxy and not to destination.
829
830---
831
832- `time` - if `true`, the request-response cycle (including all redirects) is timed at millisecond resolution. When set, the following properties are added to the response object:
833 - `elapsedTime` Duration of the entire request/response in milliseconds (*deprecated*).
834 - `responseStartTime` Timestamp when the response began (in Unix Epoch milliseconds) (*deprecated*).
835 - `timingStart` Timestamp of the start of the request (in Unix Epoch milliseconds).
836 - `timings` Contains event timestamps in millisecond resolution relative to `timingStart`. If there were redirects, the properties reflect the timings of the final request in the redirect chain:
837 - `socket` Relative timestamp when the [`http`](https://nodejs.org/api/http.html#http_event_socket) module's `socket` event fires. This happens when the socket is assigned to the request.
838 - `lookup` Relative timestamp when the [`net`](https://nodejs.org/api/net.html#net_event_lookup) module's `lookup` event fires. This happens when the DNS has been resolved.
839 - `connect`: Relative timestamp when the [`net`](https://nodejs.org/api/net.html#net_event_connect) module's `connect` event fires. This happens when the server acknowledges the TCP connection.
840 - `response`: Relative timestamp when the [`http`](https://nodejs.org/api/http.html#http_event_response) module's `response` event fires. This happens when the first bytes are received from the server.
841 - `end`: Relative timestamp when the last bytes of the response are received.
842 - `timingPhases` Contains the durations of each request phase. If there were redirects, the properties reflect the timings of the final request in the redirect chain:
843 - `wait`: Duration of socket initialization (`timings.socket`)
844 - `dns`: Duration of DNS lookup (`timings.lookup` - `timings.socket`)
845 - `tcp`: Duration of TCP connection (`timings.connect` - `timings.socket`)
846 - `firstByte`: Duration of HTTP server response (`timings.response` - `timings.connect`)
847 - `download`: Duration of HTTP download (`timings.end` - `timings.response`)
848 - `total`: Duration entire HTTP round-trip (`timings.end`)
849
850- `har` - a [HAR 1.2 Request Object](http://www.softwareishard.com/blog/har-12-spec/#request), will be processed from HAR format into options overwriting matching values *(see the [HAR 1.2 section](#support-for-har-1.2) for details)*
851- `callback` - alternatively pass the request's callback in the options object
852
853The callback argument gets 3 arguments:
854
8551. An `error` when applicable (usually from [`http.ClientRequest`](http://nodejs.org/api/http.html#http_class_http_clientrequest) object)
8562. An [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) object (Response object)
8573. The third is the `response` body (`String` or `Buffer`, or JSON object if the `json` option is supplied)
858
859[back to top](#table-of-contents)
860
861
862---
863
864## Convenience methods
865
866There are also shorthand methods for different HTTP METHODs and some other conveniences.
867
868
869### request.defaults(options)
870
871This method **returns a wrapper** around the normal request API that defaults
872to whatever options you pass to it.
873
874**Note:** `request.defaults()` **does not** modify the global request API;
875instead, it **returns a wrapper** that has your default settings applied to it.
876
877**Note:** You can call `.defaults()` on the wrapper that is returned from
878`request.defaults` to add/override defaults that were previously defaulted.
879
880For example:
881```js
882//requests using baseRequest() will set the 'x-token' header
883var baseRequest = request.defaults({
884 headers: {'x-token': 'my-token'}
885})
886
887//requests using specialRequest() will include the 'x-token' header set in
888//baseRequest and will also include the 'special' header
889var specialRequest = baseRequest.defaults({
890 headers: {special: 'special value'}
891})
892```
893
894### request.METHOD()
895
896These HTTP method convenience functions act just like `request()` but with a default method already set for you:
897
898- *request.get()*: Defaults to `method: "GET"`.
899- *request.post()*: Defaults to `method: "POST"`.
900- *request.put()*: Defaults to `method: "PUT"`.
901- *request.patch()*: Defaults to `method: "PATCH"`.
902- *request.del() / request.delete()*: Defaults to `method: "DELETE"`.
903- *request.head()*: Defaults to `method: "HEAD"`.
904- *request.options()*: Defaults to `method: "OPTIONS"`.
905
906### request.cookie()
907
908Function that creates a new cookie.
909
910```js
911request.cookie('key1=value1')
912```
913### request.jar()
914
915Function that creates a new cookie jar.
916
917```js
918request.jar()
919```
920
921[back to top](#table-of-contents)
922
923
924---
925
926
927## Debugging
928
929There are at least three ways to debug the operation of `request`:
930
9311. Launch the node process like `NODE_DEBUG=request node script.js`
932 (`lib,request,otherlib` works too).
933
9342. Set `require('request').debug = true` at any time (this does the same thing
935 as #1).
936
9373. Use the [request-debug module](https://github.com/request/request-debug) to
938 view request and response headers and bodies.
939
940[back to top](#table-of-contents)
941
942
943---
944
945## Timeouts
946
947Most requests to external servers should have a timeout attached, in case the
948server is not responding in a timely manner. Without a timeout, your code may
949have a socket open/consume resources for minutes or more.
950
951There are two main types of timeouts: **connection timeouts** and **read
952timeouts**. A connect timeout occurs if the timeout is hit while your client is
953attempting to establish a connection to a remote machine (corresponding to the
954[connect() call][connect] on the socket). A read timeout occurs any time the
955server is too slow to send back a part of the response.
956
957These two situations have widely different implications for what went wrong
958with the request, so it's useful to be able to distinguish them. You can detect
959timeout errors by checking `err.code` for an 'ETIMEDOUT' value. Further, you
960can detect whether the timeout was a connection timeout by checking if the
961`err.connect` property is set to `true`.
962
963```js
964request.get('http://10.255.255.1', {timeout: 1500}, function(err) {
965 console.log(err.code === 'ETIMEDOUT');
966 // Set to `true` if the timeout was a connection timeout, `false` or
967 // `undefined` otherwise.
968 console.log(err.connect === true);
969 process.exit(0);
970});
971```
972
973[connect]: http://linux.die.net/man/2/connect
974
975## Examples:
976
977```js
978 var request = require('request')
979 , rand = Math.floor(Math.random()*100000000).toString()
980 ;
981 request(
982 { method: 'PUT'
983 , uri: 'http://mikeal.iriscouch.com/testjs/' + rand
984 , multipart:
985 [ { 'content-type': 'application/json'
986 , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
987 }
988 , { body: 'I am an attachment' }
989 ]
990 }
991 , function (error, response, body) {
992 if(response.statusCode == 201){
993 console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)
994 } else {
995 console.log('error: '+ response.statusCode)
996 console.log(body)
997 }
998 }
999 )
1000```
1001
1002For backwards-compatibility, response compression is not supported by default.
1003To accept gzip-compressed responses, set the `gzip` option to `true`. Note
1004that the body data passed through `request` is automatically decompressed
1005while the response object is unmodified and will contain compressed data if
1006the server sent a compressed response.
1007
1008```js
1009 var request = require('request')
1010 request(
1011 { method: 'GET'
1012 , uri: 'http://www.google.com'
1013 , gzip: true
1014 }
1015 , function (error, response, body) {
1016 // body is the decompressed response body
1017 console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity'))
1018 console.log('the decoded data is: ' + body)
1019 }
1020 )
1021 .on('data', function(data) {
1022 // decompressed data as it is received
1023 console.log('decoded chunk: ' + data)
1024 })
1025 .on('response', function(response) {
1026 // unmodified http.IncomingMessage object
1027 response.on('data', function(data) {
1028 // compressed data as it is received
1029 console.log('received ' + data.length + ' bytes of compressed data')
1030 })
1031 })
1032```
1033
1034Cookies are disabled by default (else, they would be used in subsequent requests). To enable cookies, set `jar` to `true` (either in `defaults` or `options`).
1035
1036```js
1037var request = request.defaults({jar: true})
1038request('http://www.google.com', function () {
1039 request('http://images.google.com')
1040})
1041```
1042
1043To use a custom cookie jar (instead of `request`’s global cookie jar), set `jar` to an instance of `request.jar()` (either in `defaults` or `options`)
1044
1045```js
1046var j = request.jar()
1047var request = request.defaults({jar:j})
1048request('http://www.google.com', function () {
1049 request('http://images.google.com')
1050})
1051```
1052
1053OR
1054
1055```js
1056var j = request.jar();
1057var cookie = request.cookie('key1=value1');
1058var url = 'http://www.google.com';
1059j.setCookie(cookie, url);
1060request({url: url, jar: j}, function () {
1061 request('http://images.google.com')
1062})
1063```
1064
1065To use a custom cookie store (such as a
1066[`FileCookieStore`](https://github.com/mitsuru/tough-cookie-filestore)
1067which supports saving to and restoring from JSON files), pass it as a parameter
1068to `request.jar()`:
1069
1070```js
1071var FileCookieStore = require('tough-cookie-filestore');
1072// NOTE - currently the 'cookies.json' file must already exist!
1073var j = request.jar(new FileCookieStore('cookies.json'));
1074request = request.defaults({ jar : j })
1075request('http://www.google.com', function() {
1076 request('http://images.google.com')
1077})
1078```
1079
1080The cookie store must be a
1081[`tough-cookie`](https://github.com/SalesforceEng/tough-cookie)
1082store and it must support synchronous operations; see the
1083[`CookieStore` API docs](https://github.com/SalesforceEng/tough-cookie#cookiestore-api)
1084for details.
1085
1086To inspect your cookie jar after a request:
1087
1088```js
1089var j = request.jar()
1090request({url: 'http://www.google.com', jar: j}, function () {
1091 var cookie_string = j.getCookieString(url); // "key1=value1; key2=value2; ..."
1092 var cookies = j.getCookies(url);
1093 // [{key: 'key1', value: 'value1', domain: "www.google.com", ...}, ...]
1094})
1095```
1096
1097[back to top](#table-of-contents)