superagent 4.0.0-alpha.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +4 -1
- package/.zuul.yml +0 -2
- package/History.md +12 -2
- package/Makefile +10 -1
- package/Readme.md +12 -11
- package/docs/index.md +82 -49
- package/docs/test.html +6 -6
- package/dump.js +1 -0
- package/lib/client.js +1 -2
- package/lib/node/http2wrapper.js +188 -0
- package/lib/node/index.js +122 -14
- package/lib/node/response.js +1 -1
- package/lib/node/unzip.js +2 -2
- package/lib/request-base.js +8 -0
- package/package.json +13 -13
- package/superagent.js +11 -2
- package/yarn.lock +1643 -431
package/.travis.yml
CHANGED
package/.zuul.yml
CHANGED
package/History.md
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
# 4.
|
|
1
|
+
# 4.1.0 (2018-12-26)
|
|
2
|
+
|
|
3
|
+
* `.connect()` IP/DNS override option (Kornel)
|
|
4
|
+
* `.trustLocalhost()` option for allowing broken HTTPS on `localhost`
|
|
5
|
+
* `.abort()` used with promises rejects the promise.
|
|
6
|
+
|
|
7
|
+
# 4.0.0 (2018-11-17)
|
|
2
8
|
|
|
3
9
|
## Breaking changes
|
|
4
10
|
|
|
5
|
-
* Node.js v4 has reached it's end of life, so we no longer support it. It's v6+ or later.
|
|
11
|
+
* Node.js v4 has reached it's end of life, so we no longer support it. It's v6+ or later. We recommend Node.js 10.
|
|
6
12
|
* We now use ES6 in the browser code, too.
|
|
7
13
|
* If you're using Browserify or Webpack to package code for Internet Explorer, you will also have to use Babel.
|
|
8
14
|
* The pre-built node_modules/superagent.js is still ES5-compatible.
|
|
15
|
+
* `.end(…)` returns `undefined` instead of the request. If you need the request object after calling `.end()` (and you probably don't), save it in a variable and call `request.end(…)`. Consider not using `.end()` at all, and migrating to promises by calling `.then()` instead.
|
|
16
|
+
* In Node, responses with unknown MIME type are buffered by default. To get old behavior, if you use custom *unbuffered* parsers, add `.buffer(false)` to requests or set `superagent.buffer[yourMimeType] = false`.
|
|
17
|
+
* Invalid uses of `.pipe()` throw.
|
|
9
18
|
|
|
10
19
|
## Minor changes
|
|
11
20
|
|
|
@@ -16,6 +25,7 @@
|
|
|
16
25
|
* Leave backticks unencoded in query strings where possible (Ethan Resnick)
|
|
17
26
|
* Update node-mime to 2.x (Alexey Kucherenko)
|
|
18
27
|
* Allow default buffer settings based on response-type (shrey)
|
|
28
|
+
* `response.buffered` is more accurate.
|
|
19
29
|
|
|
20
30
|
# 3.8.3 (2018-04-29)
|
|
21
31
|
|
package/Makefile
CHANGED
|
@@ -9,8 +9,17 @@ test:
|
|
|
9
9
|
@if [ "x$(BROWSER)" = "x" ]; then make test-node; else make test-browser; fi
|
|
10
10
|
|
|
11
11
|
test-node:
|
|
12
|
-
@NODE_ENV=test
|
|
12
|
+
@NODE_ENV=test ./node_modules/.bin/mocha \
|
|
13
13
|
--require should \
|
|
14
|
+
--trace-warnings \
|
|
15
|
+
--reporter $(REPORTER) \
|
|
16
|
+
--timeout 5000 \
|
|
17
|
+
$(NODETESTS)
|
|
18
|
+
|
|
19
|
+
test-node-http2:
|
|
20
|
+
@NODE_ENV=test HTTP2_TEST=1 node ./node_modules/.bin/mocha \
|
|
21
|
+
--require should \
|
|
22
|
+
--trace-warnings \
|
|
14
23
|
--reporter $(REPORTER) \
|
|
15
24
|
--timeout 5000 \
|
|
16
25
|
$(NODETESTS)
|
package/Readme.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://saucelabs.com/u/shtylman-superagent)
|
|
4
4
|
|
|
5
|
-
SuperAgent is a small progressive __client-side__
|
|
5
|
+
SuperAgent is a small progressive __client-side__ and __Node.js__ HTTP request library, sporting many high-level HTTP client features. View the [docs](https://visionmedia.github.io/superagent/).
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
@@ -17,14 +17,11 @@ $ npm install superagent
|
|
|
17
17
|
Works with [browserify](https://github.com/substack/node-browserify) and [webpack](https://github.com/visionmedia/superagent/wiki/SuperAgent-for-Webpack).
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
|
-
request
|
|
20
|
+
const res = await request
|
|
21
21
|
.post('/api/pet')
|
|
22
22
|
.send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
|
|
23
23
|
.set('X-API-Key', 'foobar')
|
|
24
|
-
.set('accept', 'json')
|
|
25
|
-
.end((err, res) => {
|
|
26
|
-
// Calling the end function will send the request
|
|
27
|
-
});
|
|
24
|
+
.set('accept', 'json');
|
|
28
25
|
```
|
|
29
26
|
|
|
30
27
|
## Supported browsers and Node versions
|
|
@@ -35,7 +32,7 @@ Tested browsers:
|
|
|
35
32
|
- Latest Android, iPhone
|
|
36
33
|
- IE10 through latest. IE9 with polyfills. Even though IE9 is supported, a polyfill for `window.FormData` is required for `.field()`.
|
|
37
34
|
|
|
38
|
-
Node 6 or later is required.
|
|
35
|
+
Node 6 or later is required. For older browsers ES6-to-ES5 translation (like Babel) is required.
|
|
39
36
|
|
|
40
37
|
## Plugins
|
|
41
38
|
|
|
@@ -63,14 +60,14 @@ Existing plugins:
|
|
|
63
60
|
* [superagent-mock](https://github.com/M6Web/superagent-mock) - simulate HTTP calls by returning data fixtures based on the requested URL
|
|
64
61
|
* [superagent-mocker](https://github.com/shuvalov-anton/superagent-mocker) — simulate REST API
|
|
65
62
|
* [superagent-cache](https://github.com/jpodwys/superagent-cache) - A global SuperAgent patch with built-in, flexible caching
|
|
66
|
-
|
|
63
|
+
* [superagent-cache-plugin](https://github.com/jpodwys/superagent-cache-plugin) - A SuperAgent plugin with built-in, flexible caching
|
|
67
64
|
* [superagent-jsonapify](https://github.com/alex94puchades/superagent-jsonapify) - A lightweight [json-api](http://jsonapi.org/format/) client addon for superagent
|
|
68
65
|
* [superagent-serializer](https://github.com/zzarcon/superagent-serializer) - Converts server payload into different cases
|
|
69
|
-
* [superagent-use](https://github.com/koenpunt/superagent-use) - A client addon to apply plugins to all requests.
|
|
70
66
|
* [superagent-httpbackend](https://www.npmjs.com/package/superagent-httpbackend) - stub out requests using AngularJS' $httpBackend syntax
|
|
71
67
|
* [superagent-throttle](https://github.com/leviwheatcroft/superagent-throttle) - queues and intelligently throttles requests
|
|
72
68
|
* [superagent-charset](https://github.com/magicdawn/superagent-charset) - add charset support for node's SuperAgent
|
|
73
69
|
* [superagent-verbose-errors](https://github.com/jcoreio/superagent-verbose-errors) - include response body in error messages for failed requests
|
|
70
|
+
* [superagent-cheerio](https://github.com/mmmmmrob/superagent-cheerio) - include cheerio as `res.$` on html responses
|
|
74
71
|
|
|
75
72
|
Please prefix your plugin with `superagent-*` so that it can easily be found by others.
|
|
76
73
|
|
|
@@ -80,15 +77,19 @@ For SuperAgent extensions such as couchdb and oauth visit the [wiki](https://git
|
|
|
80
77
|
|
|
81
78
|
Our breaking changes are mostly in rarely used functionality and from stricter error handling.
|
|
82
79
|
|
|
80
|
+
* [3.x to 4.x](https://github.com/visionmedia/superagent/releases/tag/v4.0.0-alpha.1):
|
|
81
|
+
- Ensure you're running Node 6 or later. We've dropped support for Node 4.
|
|
82
|
+
- We've started using ES6 and for compatibility with Internet Explorer you may need to use Babel.
|
|
83
|
+
- We suggest migrating from `.end()` callbacks to `.then()` or `await`.
|
|
83
84
|
* [2.x to 3.x](https://github.com/visionmedia/superagent/releases/tag/v3.0.0):
|
|
84
|
-
- Ensure you're running Node 4 or later. We dropped support for Node 0.x.
|
|
85
|
+
- Ensure you're running Node 4 or later. We've dropped support for Node 0.x.
|
|
85
86
|
- Test code that calls `.send()` multiple times. Invalid calls to `.send()` will now throw instead of sending garbage.
|
|
86
87
|
* [1.x to 2.x](https://github.com/visionmedia/superagent/releases/tag/v2.0.0):
|
|
87
88
|
- If you use `.parse()` in the *browser* version, rename it to `.serialize()`.
|
|
88
89
|
- If you rely on `undefined` in query-string values being sent literally as the text "undefined", switch to checking for missing value instead. `?key=undefined` is now `?key` (without a value).
|
|
89
90
|
- If you use `.then()` in Internet Explorer, ensure that you have a polyfill that adds a global `Promise` object.
|
|
90
91
|
* 0.x to 1.x:
|
|
91
|
-
-
|
|
92
|
+
- Instead of 1-argument callback `.end(function(res){})` use `.then(res => {})`.
|
|
92
93
|
|
|
93
94
|
## Running node tests
|
|
94
95
|
|
package/docs/index.md
CHANGED
|
@@ -8,13 +8,13 @@ SuperAgent is light-weight progressive ajax API crafted for flexibility, readabi
|
|
|
8
8
|
.send({ name: 'Manny', species: 'cat' })
|
|
9
9
|
.set('X-API-Key', 'foobar')
|
|
10
10
|
.set('Accept', 'application/json')
|
|
11
|
-
.then(
|
|
11
|
+
.then(res => {
|
|
12
12
|
alert('yay got ' + JSON.stringify(res.body));
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
## Test documentation
|
|
16
16
|
|
|
17
|
-
The following [test documentation](docs/test.html) was generated with [Mocha's](
|
|
17
|
+
The following [test documentation](docs/test.html) was generated with [Mocha's](https://mochajs.org/) "doc" reporter, and directly reflects the test suite. This provides an additional source of documentation.
|
|
18
18
|
|
|
19
19
|
## Request basics
|
|
20
20
|
|
|
@@ -22,10 +22,10 @@ A request can be initiated by invoking the appropriate method on the `request` o
|
|
|
22
22
|
|
|
23
23
|
request
|
|
24
24
|
.get('/search')
|
|
25
|
-
.then(
|
|
25
|
+
.then(res => {
|
|
26
26
|
// res.body, res.headers, res.status
|
|
27
27
|
})
|
|
28
|
-
.catch(
|
|
28
|
+
.catch(err => {
|
|
29
29
|
// err.message, err.response
|
|
30
30
|
});
|
|
31
31
|
|
|
@@ -33,7 +33,7 @@ HTTP method may also be passed as a string:
|
|
|
33
33
|
|
|
34
34
|
request('GET', '/search').then(success, failure);
|
|
35
35
|
|
|
36
|
-
Old-style callbacks are also supported. *Instead of* `.then()` you can call `.end()`:
|
|
36
|
+
Old-style callbacks are also supported, but not recommended. *Instead of* `.then()` you can call `.end()`:
|
|
37
37
|
|
|
38
38
|
request('GET', '/search').end(function(err, res){
|
|
39
39
|
if (res.ok) {}
|
|
@@ -42,26 +42,28 @@ Old-style callbacks are also supported. *Instead of* `.then()` you can call `.en
|
|
|
42
42
|
Absolute URLs can be used. In web browsers absolute URLs work only if the server implements [CORS](#cors).
|
|
43
43
|
|
|
44
44
|
request
|
|
45
|
-
.get('
|
|
46
|
-
.then(
|
|
45
|
+
.get('https://example.com/search')
|
|
46
|
+
.then(res => {
|
|
47
47
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
The __Node__ client supports making requests to [Unix Domain Sockets](
|
|
50
|
+
The __Node__ client supports making requests to [Unix Domain Sockets](https://en.wikipedia.org/wiki/Unix_domain_socket):
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
// pattern: https?+unix://SOCKET_PATH/REQUEST_PATH
|
|
53
|
+
// Use `%2F` as `/` in SOCKET_PATH
|
|
54
|
+
try {
|
|
55
|
+
const res = await request
|
|
56
|
+
.get('http+unix://%2Fabsolute%2Fpath%2Fto%2Funix.sock/search');
|
|
57
|
+
// res.body, res.headers, res.status
|
|
58
|
+
} catch(err) {
|
|
59
|
+
// err.message, err.response
|
|
60
|
+
}
|
|
59
61
|
|
|
60
62
|
__DELETE__, __HEAD__, __PATCH__, __POST__, and __PUT__ requests can also be used, simply change the method name:
|
|
61
63
|
|
|
62
64
|
request
|
|
63
65
|
.head('/favicon.ico')
|
|
64
|
-
.then(
|
|
66
|
+
.then(res => {
|
|
65
67
|
|
|
66
68
|
});
|
|
67
69
|
|
|
@@ -69,7 +71,7 @@ __DELETE__ can be also called as `.del()` for compatibility with old IE where `d
|
|
|
69
71
|
|
|
70
72
|
The HTTP method defaults to __GET__, so if you wish, the following is valid:
|
|
71
73
|
|
|
72
|
-
request('/search',
|
|
74
|
+
request('/search', (err, res) => {
|
|
73
75
|
|
|
74
76
|
});
|
|
75
77
|
|
|
@@ -99,7 +101,7 @@ The `.query()` method accepts objects, which when used with the __GET__ method w
|
|
|
99
101
|
.query({ query: 'Manny' })
|
|
100
102
|
.query({ range: '1..5' })
|
|
101
103
|
.query({ order: 'desc' })
|
|
102
|
-
.then(
|
|
104
|
+
.then(res => {
|
|
103
105
|
|
|
104
106
|
});
|
|
105
107
|
|
|
@@ -108,7 +110,7 @@ Or as a single object:
|
|
|
108
110
|
request
|
|
109
111
|
.get('/search')
|
|
110
112
|
.query({ query: 'Manny', range: '1..5', order: 'desc' })
|
|
111
|
-
.then(
|
|
113
|
+
.then(res => {
|
|
112
114
|
|
|
113
115
|
});
|
|
114
116
|
|
|
@@ -117,7 +119,7 @@ The `.query()` method accepts strings as well:
|
|
|
117
119
|
request
|
|
118
120
|
.get('/querystring')
|
|
119
121
|
.query('search=Manny&range=1..5')
|
|
120
|
-
.then(
|
|
122
|
+
.then(res => {
|
|
121
123
|
|
|
122
124
|
});
|
|
123
125
|
|
|
@@ -127,7 +129,7 @@ Or joined:
|
|
|
127
129
|
.get('/querystring')
|
|
128
130
|
.query('search=Manny')
|
|
129
131
|
.query('range=1..5')
|
|
130
|
-
.then(
|
|
132
|
+
.then(res => {
|
|
131
133
|
|
|
132
134
|
});
|
|
133
135
|
|
|
@@ -138,7 +140,7 @@ You can also use the `.query()` method for HEAD requests. The following will pro
|
|
|
138
140
|
request
|
|
139
141
|
.head('/users')
|
|
140
142
|
.query({ email: 'joe@smith.com' })
|
|
141
|
-
.then(
|
|
143
|
+
.then(res => {
|
|
142
144
|
|
|
143
145
|
});
|
|
144
146
|
|
|
@@ -150,19 +152,20 @@ A typical JSON __POST__ request might look a little like the following, where we
|
|
|
150
152
|
.set('Content-Type', 'application/json')
|
|
151
153
|
.send('{"name":"tj","pet":"tobi"}')
|
|
152
154
|
.then(callback)
|
|
155
|
+
.catch(errorCallback)
|
|
153
156
|
|
|
154
157
|
Since JSON is undoubtedly the most common, it's the _default_! The following example is equivalent to the previous.
|
|
155
158
|
|
|
156
159
|
request.post('/user')
|
|
157
160
|
.send({ name: 'tj', pet: 'tobi' })
|
|
158
|
-
.then(callback)
|
|
161
|
+
.then(callback, errorCallback)
|
|
159
162
|
|
|
160
163
|
Or using multiple `.send()` calls:
|
|
161
164
|
|
|
162
165
|
request.post('/user')
|
|
163
166
|
.send({ name: 'tj' })
|
|
164
167
|
.send({ pet: 'tobi' })
|
|
165
|
-
.then(callback)
|
|
168
|
+
.then(callback, errorCallback)
|
|
166
169
|
|
|
167
170
|
By default sending strings will set the `Content-Type` to `application/x-www-form-urlencoded`,
|
|
168
171
|
multiple calls will be concatenated with `&`, here resulting in `name=tj&pet=tobi`:
|
|
@@ -170,7 +173,7 @@ By default sending strings will set the `Content-Type` to `application/x-www-for
|
|
|
170
173
|
request.post('/user')
|
|
171
174
|
.send('name=tj')
|
|
172
175
|
.send('pet=tobi')
|
|
173
|
-
.then(callback);
|
|
176
|
+
.then(callback, errorCallback);
|
|
174
177
|
|
|
175
178
|
SuperAgent formats are extensible, however by default "json" and "form" are supported. To send the data as `application/x-www-form-urlencoded` simply invoke `.type()` with "form", where the default is "json". This request will __POST__ the body "name=tj&pet=tobi".
|
|
176
179
|
|
|
@@ -178,13 +181,13 @@ SuperAgent formats are extensible, however by default "json" and "form" are supp
|
|
|
178
181
|
.type('form')
|
|
179
182
|
.send({ name: 'tj' })
|
|
180
183
|
.send({ pet: 'tobi' })
|
|
181
|
-
.then(callback)
|
|
184
|
+
.then(callback, errorCallback)
|
|
182
185
|
|
|
183
186
|
Sending a [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData) object is also supported. The following example will __POST__ the content of the HTML form identified by id="myForm":
|
|
184
187
|
|
|
185
188
|
request.post('/user')
|
|
186
189
|
.send(new FormData(document.getElementById('myForm')))
|
|
187
|
-
.then(callback)
|
|
190
|
+
.then(callback, errorCallback)
|
|
188
191
|
|
|
189
192
|
## Setting the `Content-Type`
|
|
190
193
|
|
|
@@ -216,8 +219,8 @@ request.serialize['application/xml'] = function (obj) {
|
|
|
216
219
|
return 'string generated from obj';
|
|
217
220
|
};
|
|
218
221
|
|
|
219
|
-
//going forward, all requests with a Content-type of
|
|
220
|
-
//'application/xml' will be automatically serialized
|
|
222
|
+
// going forward, all requests with a Content-type of
|
|
223
|
+
// 'application/xml' will be automatically serialized
|
|
221
224
|
```
|
|
222
225
|
If you want to send the payload in a custom format, you can replace
|
|
223
226
|
the built-in serialization with the `.serialize()` method on a per-request basis:
|
|
@@ -226,7 +229,7 @@ the built-in serialization with the `.serialize()` method on a per-request basis
|
|
|
226
229
|
request
|
|
227
230
|
.post('/user')
|
|
228
231
|
.send({foo: 'bar'})
|
|
229
|
-
.serialize(
|
|
232
|
+
.serialize(obj => {
|
|
230
233
|
return 'string generated from obj';
|
|
231
234
|
});
|
|
232
235
|
```
|
|
@@ -237,10 +240,11 @@ When given the `.retry()` method, SuperAgent will automatically retry requests,
|
|
|
237
240
|
This method has two optional arguments: number of retries (default 3) and a callback. It calls `callback(err, res)` before each retry. The callback may return `true`/`false` to control whether the request sould be retried (but the maximum number of retries is always applied).
|
|
238
241
|
|
|
239
242
|
request
|
|
240
|
-
.get('
|
|
243
|
+
.get('https://example.com/search')
|
|
241
244
|
.retry(2) // or:
|
|
242
245
|
.retry(2, callback)
|
|
243
246
|
.then(finished);
|
|
247
|
+
.catch(failed);
|
|
244
248
|
|
|
245
249
|
Use `.retry()` only with requests that are *idempotent* (i.e. multiple requests reaching the server won't cause undesirable side effects like duplicate purchases).
|
|
246
250
|
|
|
@@ -286,9 +290,7 @@ By default the query string is not assembled in any particular order. An asciibe
|
|
|
286
290
|
request.get('/user')
|
|
287
291
|
.query('name=Nick')
|
|
288
292
|
.query('search=Manny')
|
|
289
|
-
.sortQuery(
|
|
290
|
-
return a.length - b.length;
|
|
291
|
-
})
|
|
293
|
+
.sortQuery((a, b) => a.length - b.length)
|
|
292
294
|
.then(callback)
|
|
293
295
|
```
|
|
294
296
|
|
|
@@ -383,7 +385,7 @@ In browsers, you may use `.responseType('blob')` to request handling of binary r
|
|
|
383
385
|
```js
|
|
384
386
|
req.get('/binary.data')
|
|
385
387
|
.responseType('blob')
|
|
386
|
-
.
|
|
388
|
+
.then(res => {
|
|
387
389
|
// res.body will be a browser native Blob type here
|
|
388
390
|
});
|
|
389
391
|
```
|
|
@@ -444,11 +446,11 @@ To abort requests simply invoke the `req.abort()` method.
|
|
|
444
446
|
|
|
445
447
|
Sometimes networks and servers get "stuck" and never respond after accepting a request. Set timeouts to avoid requests waiting forever.
|
|
446
448
|
|
|
447
|
-
* `req.timeout({deadline:ms})` or `req.timeout(ms)` (where `ms` is a number of milliseconds > 0) sets a deadline for the entire request (including all redirects) to complete. If the response isn't fully downloaded within that time, the request will be aborted.
|
|
449
|
+
* `req.timeout({deadline:ms})` or `req.timeout(ms)` (where `ms` is a number of milliseconds > 0) sets a deadline for the entire request (including all uploads, redirects, server processing time) to complete. If the response isn't fully downloaded within that time, the request will be aborted.
|
|
448
450
|
|
|
449
|
-
* `req.timeout({response:ms})` sets maximum time to wait for the first byte to arrive from the server, but it does not limit how long the entire download can take. Response timeout should be
|
|
451
|
+
* `req.timeout({response:ms})` sets maximum time to wait for the first byte to arrive from the server, but it does not limit how long the entire download can take. Response timeout should be at least few seconds longer than just the time it takes the server to respond, because it also includes time to make DNS lookup, TCP/IP and TLS connections, and time to upload request data.
|
|
450
452
|
|
|
451
|
-
You should use both `deadline` and `response` timeouts. This way you can use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow, but reliable, networks.
|
|
453
|
+
You should use both `deadline` and `response` timeouts. This way you can use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow, but reliable, networks. Note that both of these timers limit how long *uploads* of attached files are allowed to take. Use long timeouts if you're uploading files.
|
|
452
454
|
|
|
453
455
|
request
|
|
454
456
|
.get('/big-file?network=slow')
|
|
@@ -486,10 +488,9 @@ By default only `Basic` auth is used. In browser you can add `{type:'auto'}` to
|
|
|
486
488
|
|
|
487
489
|
By default up to 5 redirects will be followed, however you may specify this with the `res.redirects(n)` method:
|
|
488
490
|
|
|
489
|
-
request
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
.then(callback);
|
|
491
|
+
const response = await request.get('/some.png').redirects(2);
|
|
492
|
+
|
|
493
|
+
Redirects exceeding the limit are treated as errors. Use `.ok(res => res.status < 400)` to read them as successful responses.
|
|
493
494
|
|
|
494
495
|
## Agents for global state
|
|
495
496
|
|
|
@@ -609,9 +610,9 @@ For security reasons, browsers will block cross-origin requests unless the serve
|
|
|
609
610
|
The `.withCredentials()` method enables the ability to send cookies from the origin, however only when `Access-Control-Allow-Origin` is _not_ a wildcard ("*"), and `Access-Control-Allow-Credentials` is "true".
|
|
610
611
|
|
|
611
612
|
request
|
|
612
|
-
.get('
|
|
613
|
+
.get('https://api.example.com:4001/')
|
|
613
614
|
.withCredentials()
|
|
614
|
-
.then(
|
|
615
|
+
.then(res => {
|
|
615
616
|
assert.equal(200, res.status);
|
|
616
617
|
assert.equal('tobi', res.text);
|
|
617
618
|
})
|
|
@@ -623,7 +624,7 @@ Your callback function will always be passed two arguments: error and response.
|
|
|
623
624
|
request
|
|
624
625
|
.post('/upload')
|
|
625
626
|
.attach('image', 'path/to/tobi.png')
|
|
626
|
-
.then(
|
|
627
|
+
.then(res => {
|
|
627
628
|
|
|
628
629
|
});
|
|
629
630
|
|
|
@@ -633,7 +634,7 @@ An "error" event is also emitted, with you can listen for:
|
|
|
633
634
|
.post('/upload')
|
|
634
635
|
.attach('image', 'path/to/tobi.png')
|
|
635
636
|
.on('error', handle)
|
|
636
|
-
.then(
|
|
637
|
+
.then(res => {
|
|
637
638
|
|
|
638
639
|
});
|
|
639
640
|
|
|
@@ -673,11 +674,43 @@ SuperAgent fires `progress` events on upload and download of large files.
|
|
|
673
674
|
loaded: // bytes downloaded or uploaded so far
|
|
674
675
|
} */
|
|
675
676
|
})
|
|
676
|
-
.
|
|
677
|
+
.then()
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
## Testing on localhost
|
|
681
|
+
|
|
682
|
+
### Forcing specific connection IP address
|
|
683
|
+
|
|
684
|
+
In Node.js it's possible to ignore DNS resolution and direct all requests to a specific IP address using `.connect()` method. For example, this request will go to localhost instead of `example.com`:
|
|
685
|
+
|
|
686
|
+
const res = await request.get("http://example.com").connect("127.0.0.1");
|
|
687
|
+
|
|
688
|
+
Because the request may be redirected, it's possible to specify multiple hostnames and multiple IPs, as well as a special `*` as the fallback (note: other wildcards are not supported). The requests will keep their `Host` header with the original value. `.connect(undefined)` turns off the feature.
|
|
689
|
+
|
|
690
|
+
const res = await request.get("http://redir.example.com:555")
|
|
691
|
+
.connect({
|
|
692
|
+
"redir.example.com": "127.0.0.1", // redir.example.com:555 will use 127.0.0.1:555
|
|
693
|
+
"www.example.com": false, // don't override this one; use DNS as normal
|
|
694
|
+
"*": "proxy.example.com", // all other requests will go to this host
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
### Ignoring broken/insecure HTTPS on localhost
|
|
698
|
+
|
|
699
|
+
In Node.js, when HTTPS is misconfigured and insecure (e.g. using self-signed certificate *without* specifying own `.ca()`), it's still possible to permit requests to `localhost` by calling `.trustLocalhost()`:
|
|
700
|
+
|
|
701
|
+
const res = await request.get("https://localhost").trustLocalhost()
|
|
702
|
+
|
|
703
|
+
Together with `.connect("127.0.0.1")` this may be used to force HTTPS requests to any domain to be re-routed to `localhost` instead.
|
|
704
|
+
|
|
705
|
+
It's generally safe to ignore broken HTTPS on `localhost`, because the loopback interface is not exposed to untrusted networks. Trusting `localhost` may become the default in the future. Use `.trustLocalhost(false)` to force check of `127.0.0.1`'s authenticity.
|
|
706
|
+
|
|
707
|
+
We intentionally don't support disabling of HTTPS security when making requests to any other IP, because such options end up abused as a quick "fix" for HTTPS problems. You can get free HTTPS certificates from [Let's Encrypt](https://certbot.eff.org) or set your own CA (`.ca(ca_public_pem)`) to make your self-signed certificates trusted.
|
|
677
708
|
|
|
678
709
|
## Promise and Generator support
|
|
679
710
|
|
|
680
|
-
SuperAgent's request is a "thenable" object that's compatible with JavaScript promises and `async`/`await` syntax.
|
|
711
|
+
SuperAgent's request is a "thenable" object that's compatible with JavaScript promises and the `async`/`await` syntax.
|
|
712
|
+
|
|
713
|
+
const res = await request.get(url);
|
|
681
714
|
|
|
682
715
|
If you're using promises, **do not** call `.end()` or `.pipe()`. Any use of `.then()` or `await` disables all other ways of using the request.
|
|
683
716
|
|
|
@@ -698,4 +731,4 @@ If want to use WebPack to compile code for Node.JS, you *must* specify [node tar
|
|
|
698
731
|
|
|
699
732
|
### Using browser version in electron
|
|
700
733
|
|
|
701
|
-
[Electron](
|
|
734
|
+
[Electron](https://electron.atom.io/) developers report if you would prefer to use the browser version of SuperAgent instead of the Node version, you can `require('superagent/superagent')`. Your requests will now show up in the Chrome developer tools Network tab. Note this environment is not covered by automated test suite and not officially supported.
|
package/docs/test.html
CHANGED
|
@@ -265,7 +265,7 @@
|
|
|
265
265
|
.post(uri + '/echo')
|
|
266
266
|
.send({ name: 'tobi' })
|
|
267
267
|
.end(function(err, res){
|
|
268
|
-
assert.
|
|
268
|
+
assert.ifError(err)
|
|
269
269
|
res.text.should.equal('{"name":"tobi"}');
|
|
270
270
|
done();
|
|
271
271
|
});</code></pre></dd>
|
|
@@ -662,7 +662,7 @@ request
|
|
|
662
662
|
.get('http://localhost:5000/custom')
|
|
663
663
|
.buffer()
|
|
664
664
|
.end(function(err, res){
|
|
665
|
-
assert.
|
|
665
|
+
assert.ifError(err)
|
|
666
666
|
assert.equal('custom stuff', res.text);
|
|
667
667
|
assert(res.buffered);
|
|
668
668
|
done();
|
|
@@ -679,7 +679,7 @@ request
|
|
|
679
679
|
.send('hello this is dog')
|
|
680
680
|
.buffer(false)
|
|
681
681
|
.end(function(err, res){
|
|
682
|
-
assert.
|
|
682
|
+
assert.ifError(err)
|
|
683
683
|
assert.equal(null, res.text);
|
|
684
684
|
res.body.should.eql({});
|
|
685
685
|
var buf = '';
|
|
@@ -734,7 +734,7 @@ done();</code></pre></dd>
|
|
|
734
734
|
.type('application/x-dog')
|
|
735
735
|
.send('hello this is dog')
|
|
736
736
|
.end(function(err, res){
|
|
737
|
-
assert.
|
|
737
|
+
assert.ifError(err)
|
|
738
738
|
assert.equal(null, res.text);
|
|
739
739
|
res.body.should.eql({});
|
|
740
740
|
var buf = '';
|
|
@@ -761,7 +761,7 @@ request
|
|
|
761
761
|
.send(img)
|
|
762
762
|
.buffer(false)
|
|
763
763
|
.end(function(err, res){
|
|
764
|
-
assert.
|
|
764
|
+
assert.ifError(err)
|
|
765
765
|
assert(!res.buffered);
|
|
766
766
|
assert.equal(res.header['content-length'], Buffer.byteLength(img));
|
|
767
767
|
done();
|
|
@@ -774,7 +774,7 @@ request
|
|
|
774
774
|
.send(img)
|
|
775
775
|
.buffer(true)
|
|
776
776
|
.end(function(err, res){
|
|
777
|
-
assert.
|
|
777
|
+
assert.ifError(err)
|
|
778
778
|
assert(res.buffered);
|
|
779
779
|
assert.equal(res.header['content-length'], img.length);
|
|
780
780
|
done();
|
package/dump.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/lib/client.js
CHANGED
|
@@ -673,7 +673,7 @@ Request.prototype.end = function(fn){
|
|
|
673
673
|
// querystring
|
|
674
674
|
this._finalizeQueryString();
|
|
675
675
|
|
|
676
|
-
|
|
676
|
+
this._end();
|
|
677
677
|
};
|
|
678
678
|
|
|
679
679
|
Request.prototype._end = function() {
|
|
@@ -772,7 +772,6 @@ Request.prototype._end = function() {
|
|
|
772
772
|
// IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
|
|
773
773
|
// We need null here if data is undefined
|
|
774
774
|
xhr.send(typeof data !== 'undefined' ? data : null);
|
|
775
|
-
return this;
|
|
776
775
|
};
|
|
777
776
|
|
|
778
777
|
request.agent = () => new Agent();
|