superagent 3.8.0-alpha.1 → 3.8.3
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/History.md +25 -0
- package/Readme.md +1 -0
- package/docs/index.md +125 -55
- package/lib/client.js +6 -6
- package/lib/node/index.js +78 -40
- package/lib/request-base.js +44 -2
- package/lib/response-base.js +2 -0
- package/lib/utils.js +4 -2
- package/package.json +6 -6
- package/superagent.js +62 -43
- package/test.js +7 -0
- package/yarn.lock +420 -824
- package/lib/should-retry.js +0 -25
package/History.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
# 3.8.3 (2018-04-29)
|
|
3
|
+
|
|
4
|
+
* Add flags for 201 & 422 responses (Nikhil Fadnis)
|
|
5
|
+
* Emit progress event while uploading Node `Buffer` via send method (Sergey Akhalkov)
|
|
6
|
+
* Fixed setting correct cookies for redirects (Damien Clark)
|
|
7
|
+
* Replace .catch with ['catch'] for IE9 Support (Miguel Stevens)
|
|
8
|
+
|
|
9
|
+
# 3.8.2 (2017-12-09)
|
|
10
|
+
|
|
11
|
+
* Fixed handling of exceptions thrown from callbacks
|
|
12
|
+
* Stricter matching of `+json` MIME types.
|
|
13
|
+
|
|
14
|
+
# 3.8.1 (2017-11-08)
|
|
15
|
+
|
|
16
|
+
* Clear authorization header on cross-domain redirect
|
|
17
|
+
|
|
18
|
+
# 3.8.0
|
|
19
|
+
|
|
20
|
+
* Added support for "globally" defined headers and event handlers via `superagent.agent()`. It now remembers default settings for all its requests.
|
|
21
|
+
* Added optional callback to `.retry()` (Alexander Murphy)
|
|
22
|
+
* Unified auth args handling in node/browser (Edmundo Alvarez)
|
|
23
|
+
* Fixed error handling in zlib pipes (Kornel)
|
|
24
|
+
* Documented that 3xx status codes are errors (Mickey Reiss)
|
|
25
|
+
|
|
1
26
|
# 3.7.0 (2017-10-17)
|
|
2
27
|
|
|
3
28
|
* Limit maximum response size. Prevents zip bombs (Kornel)
|
package/Readme.md
CHANGED
|
@@ -70,6 +70,7 @@ Existing plugins:
|
|
|
70
70
|
* [superagent-httpbackend](https://www.npmjs.com/package/superagent-httpbackend) - stub out requests using AngularJS' $httpBackend syntax
|
|
71
71
|
* [superagent-throttle](https://github.com/leviwheatcroft/superagent-throttle) - queues and intelligently throttles requests
|
|
72
72
|
* [superagent-charset](https://github.com/magicdawn/superagent-charset) - add charset support for node's SuperAgent
|
|
73
|
+
* [superagent-verbose-errors](https://github.com/jcoreio/superagent-verbose-errors) - include response body in error messages for failed requests
|
|
73
74
|
|
|
74
75
|
Please prefix your plugin with `superagent-*` so that it can easily be found by others.
|
|
75
76
|
|
package/docs/index.md
CHANGED
|
@@ -8,12 +8,8 @@ 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
|
-
.
|
|
12
|
-
|
|
13
|
-
alert('Oh no! error');
|
|
14
|
-
} else {
|
|
15
|
-
alert('yay got ' + JSON.stringify(res.body));
|
|
16
|
-
}
|
|
11
|
+
.then(function(res) {
|
|
12
|
+
alert('yay got ' + JSON.stringify(res.body));
|
|
17
13
|
});
|
|
18
14
|
|
|
19
15
|
## Test documentation
|
|
@@ -22,27 +18,32 @@ The following [test documentation](docs/test.html) was generated with [Mocha's](
|
|
|
22
18
|
|
|
23
19
|
## Request basics
|
|
24
20
|
|
|
25
|
-
A request can be initiated by invoking the appropriate method on the `request` object, then calling `.end()` to send the request. For example a simple __GET__ request:
|
|
21
|
+
A request can be initiated by invoking the appropriate method on the `request` object, then calling `.then()` (or `.end()` [or `await`](#promise-and-generator-support)) to send the request. For example a simple __GET__ request:
|
|
26
22
|
|
|
27
23
|
request
|
|
28
24
|
.get('/search')
|
|
29
|
-
.
|
|
30
|
-
|
|
25
|
+
.then(function(res) {
|
|
26
|
+
// res.body, res.headers, res.status
|
|
27
|
+
})
|
|
28
|
+
.catch(function(err) {
|
|
29
|
+
// err.message, err.response
|
|
31
30
|
});
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
HTTP method may also be passed as a string:
|
|
34
33
|
|
|
35
|
-
request('GET', '/search').
|
|
34
|
+
request('GET', '/search').then(success, failure);
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
Old-style callbacks are also supported. *Instead of* `.then()` you can call `.end()`:
|
|
38
37
|
|
|
39
|
-
request('GET', '/search').
|
|
38
|
+
request('GET', '/search').end(function(err, res){
|
|
39
|
+
if (res.ok) {}
|
|
40
|
+
});
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
Absolute URLs can be used. In web browsers absolute URLs work only if the server implements [CORS](#cors).
|
|
42
43
|
|
|
43
44
|
request
|
|
44
45
|
.get('http://example.com/search')
|
|
45
|
-
.
|
|
46
|
+
.then(function(res) {
|
|
46
47
|
|
|
47
48
|
});
|
|
48
49
|
|
|
@@ -52,7 +53,7 @@ The __Node__ client supports making requests to [Unix Domain Sockets](http://en.
|
|
|
52
53
|
// Use `%2F` as `/` in SOCKET_PATH
|
|
53
54
|
request
|
|
54
55
|
.get('http+unix://%2Fabsolute%2Fpath%2Fto%2Funix.sock/search')
|
|
55
|
-
.
|
|
56
|
+
.then(res => {
|
|
56
57
|
|
|
57
58
|
});
|
|
58
59
|
|
|
@@ -60,13 +61,13 @@ __DELETE__, __HEAD__, __PATCH__, __POST__, and __PUT__ requests can also be used
|
|
|
60
61
|
|
|
61
62
|
request
|
|
62
63
|
.head('/favicon.ico')
|
|
63
|
-
.
|
|
64
|
+
.then(function(res) {
|
|
64
65
|
|
|
65
66
|
});
|
|
66
67
|
|
|
67
68
|
__DELETE__ can be also called as `.del()` for compatibility with old IE where `delete` is a reserved word.
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
The HTTP method defaults to __GET__, so if you wish, the following is valid:
|
|
70
71
|
|
|
71
72
|
request('/search', function(err, res){
|
|
72
73
|
|
|
@@ -80,14 +81,14 @@ Setting header fields is simple, invoke `.set()` with a field name and value:
|
|
|
80
81
|
.get('/search')
|
|
81
82
|
.set('API-Key', 'foobar')
|
|
82
83
|
.set('Accept', 'application/json')
|
|
83
|
-
.
|
|
84
|
+
.then(callback);
|
|
84
85
|
|
|
85
86
|
You may also pass an object to set several fields in a single call:
|
|
86
87
|
|
|
87
88
|
request
|
|
88
89
|
.get('/search')
|
|
89
90
|
.set({ 'API-Key': 'foobar', Accept: 'application/json' })
|
|
90
|
-
.
|
|
91
|
+
.then(callback);
|
|
91
92
|
|
|
92
93
|
## `GET` requests
|
|
93
94
|
|
|
@@ -98,7 +99,7 @@ The `.query()` method accepts objects, which when used with the __GET__ method w
|
|
|
98
99
|
.query({ query: 'Manny' })
|
|
99
100
|
.query({ range: '1..5' })
|
|
100
101
|
.query({ order: 'desc' })
|
|
101
|
-
.
|
|
102
|
+
.then(function(res) {
|
|
102
103
|
|
|
103
104
|
});
|
|
104
105
|
|
|
@@ -107,7 +108,7 @@ Or as a single object:
|
|
|
107
108
|
request
|
|
108
109
|
.get('/search')
|
|
109
110
|
.query({ query: 'Manny', range: '1..5', order: 'desc' })
|
|
110
|
-
.
|
|
111
|
+
.then(function(res) {
|
|
111
112
|
|
|
112
113
|
});
|
|
113
114
|
|
|
@@ -116,7 +117,7 @@ The `.query()` method accepts strings as well:
|
|
|
116
117
|
request
|
|
117
118
|
.get('/querystring')
|
|
118
119
|
.query('search=Manny&range=1..5')
|
|
119
|
-
.
|
|
120
|
+
.then(function(res) {
|
|
120
121
|
|
|
121
122
|
});
|
|
122
123
|
|
|
@@ -126,7 +127,7 @@ Or joined:
|
|
|
126
127
|
.get('/querystring')
|
|
127
128
|
.query('search=Manny')
|
|
128
129
|
.query('range=1..5')
|
|
129
|
-
.
|
|
130
|
+
.then(function(res) {
|
|
130
131
|
|
|
131
132
|
});
|
|
132
133
|
|
|
@@ -137,7 +138,7 @@ You can also use the `.query()` method for HEAD requests. The following will pro
|
|
|
137
138
|
request
|
|
138
139
|
.head('/users')
|
|
139
140
|
.query({ email: 'joe@smith.com' })
|
|
140
|
-
.
|
|
141
|
+
.then(function(res) {
|
|
141
142
|
|
|
142
143
|
});
|
|
143
144
|
|
|
@@ -148,20 +149,20 @@ A typical JSON __POST__ request might look a little like the following, where we
|
|
|
148
149
|
request.post('/user')
|
|
149
150
|
.set('Content-Type', 'application/json')
|
|
150
151
|
.send('{"name":"tj","pet":"tobi"}')
|
|
151
|
-
.
|
|
152
|
+
.then(callback)
|
|
152
153
|
|
|
153
154
|
Since JSON is undoubtedly the most common, it's the _default_! The following example is equivalent to the previous.
|
|
154
155
|
|
|
155
156
|
request.post('/user')
|
|
156
157
|
.send({ name: 'tj', pet: 'tobi' })
|
|
157
|
-
.
|
|
158
|
+
.then(callback)
|
|
158
159
|
|
|
159
160
|
Or using multiple `.send()` calls:
|
|
160
161
|
|
|
161
162
|
request.post('/user')
|
|
162
163
|
.send({ name: 'tj' })
|
|
163
164
|
.send({ pet: 'tobi' })
|
|
164
|
-
.
|
|
165
|
+
.then(callback)
|
|
165
166
|
|
|
166
167
|
By default sending strings will set the `Content-Type` to `application/x-www-form-urlencoded`,
|
|
167
168
|
multiple calls will be concatenated with `&`, here resulting in `name=tj&pet=tobi`:
|
|
@@ -169,7 +170,7 @@ By default sending strings will set the `Content-Type` to `application/x-www-for
|
|
|
169
170
|
request.post('/user')
|
|
170
171
|
.send('name=tj')
|
|
171
172
|
.send('pet=tobi')
|
|
172
|
-
.
|
|
173
|
+
.then(callback);
|
|
173
174
|
|
|
174
175
|
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".
|
|
175
176
|
|
|
@@ -177,13 +178,13 @@ SuperAgent formats are extensible, however by default "json" and "form" are supp
|
|
|
177
178
|
.type('form')
|
|
178
179
|
.send({ name: 'tj' })
|
|
179
180
|
.send({ pet: 'tobi' })
|
|
180
|
-
.
|
|
181
|
+
.then(callback)
|
|
181
182
|
|
|
182
183
|
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":
|
|
183
184
|
|
|
184
185
|
request.post('/user')
|
|
185
186
|
.send(new FormData(document.getElementById('myForm')))
|
|
186
|
-
.
|
|
187
|
+
.then(callback)
|
|
187
188
|
|
|
188
189
|
## Setting the `Content-Type`
|
|
189
190
|
|
|
@@ -207,16 +208,41 @@ simply the extension name such as "xml", "json", "png", etc:
|
|
|
207
208
|
|
|
208
209
|
## Serializing request body
|
|
209
210
|
|
|
210
|
-
SuperAgent will automatically serialize JSON and forms.
|
|
211
|
+
SuperAgent will automatically serialize JSON and forms.
|
|
212
|
+
You can setup automatic serialization for other types as well:
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
request.serialize['application/xml'] = function (obj) {
|
|
216
|
+
return 'string generated from obj';
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
//going forward, all requests with a Content-type of
|
|
220
|
+
//'application/xml' will be automatically serialized
|
|
221
|
+
```
|
|
222
|
+
If you want to send the payload in a custom format, you can replace
|
|
223
|
+
the built-in serialization with the `.serialize()` method on a per-request basis:
|
|
211
224
|
|
|
225
|
+
```js
|
|
226
|
+
request
|
|
227
|
+
.post('/user')
|
|
228
|
+
.send({foo: 'bar'})
|
|
229
|
+
.serialize(function serializer(obj) {
|
|
230
|
+
return 'string generated from obj';
|
|
231
|
+
});
|
|
232
|
+
```
|
|
212
233
|
## Retrying requests
|
|
213
234
|
|
|
214
|
-
When given the `.retry()` method, SuperAgent will automatically retry requests, if they fail in a way that is transient or could be due to a flaky Internet connection.
|
|
235
|
+
When given the `.retry()` method, SuperAgent will automatically retry requests, if they fail in a way that is transient or could be due to a flaky Internet connection.
|
|
236
|
+
|
|
237
|
+
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).
|
|
215
238
|
|
|
216
239
|
request
|
|
217
240
|
.get('http://example.com/search')
|
|
218
|
-
.retry(2)
|
|
219
|
-
.
|
|
241
|
+
.retry(2) // or:
|
|
242
|
+
.retry(2, callback)
|
|
243
|
+
.then(finished);
|
|
244
|
+
|
|
245
|
+
Use `.retry()` only with requests that are *idempotent* (i.e. multiple requests reaching the server won't cause undesirable side effects like duplicate purchases).
|
|
220
246
|
|
|
221
247
|
## Setting Accept
|
|
222
248
|
|
|
@@ -244,7 +270,7 @@ If you are calling Facebook's API, be sure to send an `Accept: application/json`
|
|
|
244
270
|
.query({ format: 'json' })
|
|
245
271
|
.query({ dest: '/login' })
|
|
246
272
|
.send({ post: 'data', here: 'wahoo' })
|
|
247
|
-
.
|
|
273
|
+
.then(callback);
|
|
248
274
|
|
|
249
275
|
By default the query string is not assembled in any particular order. An asciibetically-sorted query string can be enabled with `req.sortQuery()`. You may also provide a custom sorting comparison function with `req.sortQuery(myComparisonFn)`. The comparison function should take 2 arguments and return a negative/zero/positive integer.
|
|
250
276
|
|
|
@@ -254,7 +280,7 @@ By default the query string is not assembled in any particular order. An asciibe
|
|
|
254
280
|
.query('name=Nick')
|
|
255
281
|
.query('search=Manny')
|
|
256
282
|
.sortQuery()
|
|
257
|
-
.
|
|
283
|
+
.then(callback)
|
|
258
284
|
|
|
259
285
|
// customized sort function
|
|
260
286
|
request.get('/user')
|
|
@@ -263,7 +289,7 @@ By default the query string is not assembled in any particular order. An asciibe
|
|
|
263
289
|
.sortQuery(function(a, b){
|
|
264
290
|
return a.length - b.length;
|
|
265
291
|
})
|
|
266
|
-
.
|
|
292
|
+
.then(callback)
|
|
267
293
|
```
|
|
268
294
|
|
|
269
295
|
## TLS options
|
|
@@ -285,7 +311,7 @@ request
|
|
|
285
311
|
.post('/client-auth')
|
|
286
312
|
.key(key)
|
|
287
313
|
.cert(cert)
|
|
288
|
-
.
|
|
314
|
+
.then(callback);
|
|
289
315
|
```
|
|
290
316
|
|
|
291
317
|
```js
|
|
@@ -294,12 +320,32 @@ var ca = fs.readFileSync('ca.cert.pem');
|
|
|
294
320
|
request
|
|
295
321
|
.post('https://localhost/private-ca-server')
|
|
296
322
|
.ca(ca)
|
|
297
|
-
.
|
|
323
|
+
.then(res => {});
|
|
298
324
|
```
|
|
299
325
|
|
|
300
326
|
## Parsing response bodies
|
|
301
327
|
|
|
302
|
-
SuperAgent will parse known response-body data for you,
|
|
328
|
+
SuperAgent will parse known response-body data for you,
|
|
329
|
+
currently supporting `application/x-www-form-urlencoded`,
|
|
330
|
+
`application/json`, and `multipart/form-data`. You can setup
|
|
331
|
+
automatic parsing for other response-body data as well:
|
|
332
|
+
|
|
333
|
+
```js
|
|
334
|
+
//browser
|
|
335
|
+
request.parse['application/xml'] = function (str) {
|
|
336
|
+
return {'object': 'parsed from str'};
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
//node
|
|
340
|
+
request.parse['application/xml'] = function (res, cb) {
|
|
341
|
+
//parse response text and set res.body here
|
|
342
|
+
|
|
343
|
+
cb(null, res);
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
//going forward, responses of type 'application/xml'
|
|
347
|
+
//will be parsed automatically
|
|
348
|
+
```
|
|
303
349
|
|
|
304
350
|
You can set a custom parser (that takes precedence over built-in parsers) with the `.buffer(true).parse(fn)` method. If response buffering is not enabled (`.buffer(false)`) then the `response` event will be emitted without waiting for the body parser to finish, so `response.body` won't be available.
|
|
305
351
|
|
|
@@ -410,8 +456,10 @@ You should use both `deadline` and `response` timeouts. This way you can use a s
|
|
|
410
456
|
response: 5000, // Wait 5 seconds for the server to start sending,
|
|
411
457
|
deadline: 60000, // but allow 1 minute for the file to finish loading.
|
|
412
458
|
})
|
|
413
|
-
.
|
|
414
|
-
|
|
459
|
+
.then(res => {
|
|
460
|
+
/* responded in time */
|
|
461
|
+
}, err => {
|
|
462
|
+
if (err.timeout) { /* timed out! */ } else { /* other error */ }
|
|
415
463
|
});
|
|
416
464
|
|
|
417
465
|
Timeout errors have a `.timeout` property.
|
|
@@ -423,12 +471,12 @@ In both Node and browsers auth available via the `.auth()` method:
|
|
|
423
471
|
request
|
|
424
472
|
.get('http://local')
|
|
425
473
|
.auth('tobi', 'learnboost')
|
|
426
|
-
.
|
|
474
|
+
.then(callback);
|
|
427
475
|
|
|
428
476
|
|
|
429
477
|
In the _Node_ client Basic auth can be in the URL as "user:pass":
|
|
430
478
|
|
|
431
|
-
request.get('http://tobi:learnboost@local').
|
|
479
|
+
request.get('http://tobi:learnboost@local').then(callback);
|
|
432
480
|
|
|
433
481
|
By default only `Basic` auth is used. In browser you can add `{type:'auto'}` to enable all methods built-in in the browser (Digest, NTLM, etc.):
|
|
434
482
|
|
|
@@ -441,7 +489,7 @@ By default up to 5 redirects will be followed, however you may specify this with
|
|
|
441
489
|
request
|
|
442
490
|
.get('/some.png')
|
|
443
491
|
.redirects(2)
|
|
444
|
-
.
|
|
492
|
+
.then(callback);
|
|
445
493
|
|
|
446
494
|
## Agents for global state
|
|
447
495
|
|
|
@@ -460,7 +508,7 @@ In browsers cookies are managed automatically by the browser, so the `.agent()`
|
|
|
460
508
|
|
|
461
509
|
### Default options for multiple requests
|
|
462
510
|
|
|
463
|
-
Regular request methods
|
|
511
|
+
Regular request methods called on the agent will be used as defaults for all requests made by that agent.
|
|
464
512
|
|
|
465
513
|
const agent = request.agent()
|
|
466
514
|
.use(plugin)
|
|
@@ -469,9 +517,13 @@ Regular request methods (`.use()`, `.set()`, `.auth()`) called on the agent will
|
|
|
469
517
|
await agent.get('/with-plugin-and-auth');
|
|
470
518
|
await agent.get('/also-with-plugin-and-auth');
|
|
471
519
|
|
|
520
|
+
The complete list of methods that the agent can use to set defaults is: `use`, `on`, `once`, `set`, `query`, `type`, `accept`, `auth`, `withCredentials`, `sortQuery`, `retry`, `ok`, `redirects`, `timeout`, `buffer`, `serialize`, `parse`, `ca`, `key`, `pfx`, `cert`.
|
|
521
|
+
|
|
472
522
|
## Piping data
|
|
473
523
|
|
|
474
|
-
The Node client allows you to pipe data to and from the request.
|
|
524
|
+
The Node client allows you to pipe data to and from the request. Please note that `.pipe()` is used **instead of** `.end()`/`.then()` methods.
|
|
525
|
+
|
|
526
|
+
For example piping a file's contents as the request:
|
|
475
527
|
|
|
476
528
|
const request = require('superagent');
|
|
477
529
|
const fs = require('fs');
|
|
@@ -489,6 +541,22 @@ Or piping the response to a file:
|
|
|
489
541
|
const req = request.get('/some.json');
|
|
490
542
|
req.pipe(stream);
|
|
491
543
|
|
|
544
|
+
It's not possible to mix pipes and callbacks or promises. Note that you should **NOT** attempt to pipe the result of `.end()` or the `Response` object:
|
|
545
|
+
|
|
546
|
+
// Don't do either of these:
|
|
547
|
+
const stream = getAWritableStream();
|
|
548
|
+
const req = request
|
|
549
|
+
.get('/some.json')
|
|
550
|
+
// BAD: this pipes garbage to the stream and fails in unexpected ways
|
|
551
|
+
.end((err, this_does_not_work) => this_does_not_work.pipe(stream))
|
|
552
|
+
const req = request
|
|
553
|
+
.get('/some.json')
|
|
554
|
+
.end()
|
|
555
|
+
// BAD: this is also unsupported, .pipe calls .end for you.
|
|
556
|
+
.pipe(nope_its_too_late);
|
|
557
|
+
|
|
558
|
+
In a [future version](https://github.com/visionmedia/superagent/issues/1188) of superagent, improper calls to `pipe()` will fail.
|
|
559
|
+
|
|
492
560
|
## Multipart requests
|
|
493
561
|
|
|
494
562
|
SuperAgent is also great for _building_ multipart requests for which it provides methods `.attach()` and `.field()`.
|
|
@@ -499,7 +567,7 @@ When you use `.field()` or `.attach()` you can't use `.send()` and you *must not
|
|
|
499
567
|
|
|
500
568
|
To send a file use `.attach(name, [file], [options])`. You can attach multiple files by calling `.attach` multiple times. The arguments are:
|
|
501
569
|
|
|
502
|
-
* `name` —
|
|
570
|
+
* `name` — field name in the form.
|
|
503
571
|
* `file` — either string with file path or `Blob`/`Buffer` object.
|
|
504
572
|
* `options` — (optional) either string with custom file name or `{filename: string}` object. In Node also `{contentType: 'mime/type'}` is supported. In browser create a `Blob` with an appropriate type instead.
|
|
505
573
|
|
|
@@ -510,7 +578,7 @@ To send a file use `.attach(name, [file], [options])`. You can attach multiple f
|
|
|
510
578
|
.attach('image1', 'path/to/felix.jpeg')
|
|
511
579
|
.attach('image2', imageBuffer, 'luna.jpeg')
|
|
512
580
|
.field('caption', 'My cats')
|
|
513
|
-
.
|
|
581
|
+
.then(callback);
|
|
514
582
|
|
|
515
583
|
### Field values
|
|
516
584
|
|
|
@@ -522,7 +590,7 @@ Much like form fields in HTML, you can set field values with `.field(name, value
|
|
|
522
590
|
.field('user[email]', 'tobi@learnboost.com')
|
|
523
591
|
.field('friends[]', ['loki', 'jane'])
|
|
524
592
|
.attach('image', 'path/to/tobi.png')
|
|
525
|
-
.
|
|
593
|
+
.then(callback);
|
|
526
594
|
|
|
527
595
|
## Compression
|
|
528
596
|
|
|
@@ -543,7 +611,7 @@ The `.withCredentials()` method enables the ability to send cookies from the ori
|
|
|
543
611
|
request
|
|
544
612
|
.get('http://api.example.com:4001/')
|
|
545
613
|
.withCredentials()
|
|
546
|
-
.then(function(res){
|
|
614
|
+
.then(function(res) {
|
|
547
615
|
assert.equal(200, res.status);
|
|
548
616
|
assert.equal('tobi', res.text);
|
|
549
617
|
})
|
|
@@ -555,7 +623,7 @@ Your callback function will always be passed two arguments: error and response.
|
|
|
555
623
|
request
|
|
556
624
|
.post('/upload')
|
|
557
625
|
.attach('image', 'path/to/tobi.png')
|
|
558
|
-
.
|
|
626
|
+
.then(function(res) {
|
|
559
627
|
|
|
560
628
|
});
|
|
561
629
|
|
|
@@ -565,7 +633,7 @@ An "error" event is also emitted, with you can listen for:
|
|
|
565
633
|
.post('/upload')
|
|
566
634
|
.attach('image', 'path/to/tobi.png')
|
|
567
635
|
.on('error', handle)
|
|
568
|
-
.
|
|
636
|
+
.then(function(res) {
|
|
569
637
|
|
|
570
638
|
});
|
|
571
639
|
|
|
@@ -609,7 +677,9 @@ SuperAgent fires `progress` events on upload and download of large files.
|
|
|
609
677
|
|
|
610
678
|
## Promise and Generator support
|
|
611
679
|
|
|
612
|
-
SuperAgent's request is a "thenable" object that's compatible with JavaScript promises and `async`/`await` syntax.
|
|
680
|
+
SuperAgent's request is a "thenable" object that's compatible with JavaScript promises and `async`/`await` syntax.
|
|
681
|
+
|
|
682
|
+
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.
|
|
613
683
|
|
|
614
684
|
Libraries like [co](https://github.com/tj/co) or a web framework like [koa](https://github.com/koajs/koa) can `yield` on any SuperAgent method:
|
|
615
685
|
|
package/lib/client.js
CHANGED
|
@@ -17,7 +17,6 @@ var RequestBase = require('./request-base');
|
|
|
17
17
|
var isObject = require('./is-object');
|
|
18
18
|
var ResponseBase = require('./response-base');
|
|
19
19
|
var Agent = require('./agent-base');
|
|
20
|
-
var shouldRetry = require('./should-retry');
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* Noop.
|
|
@@ -187,7 +186,7 @@ request.types = {
|
|
|
187
186
|
|
|
188
187
|
request.serialize = {
|
|
189
188
|
'application/x-www-form-urlencoded': serialize,
|
|
190
|
-
'application/json': JSON.stringify
|
|
189
|
+
'application/json': JSON.stringify
|
|
191
190
|
};
|
|
192
191
|
|
|
193
192
|
/**
|
|
@@ -201,7 +200,7 @@ request.serialize = {
|
|
|
201
200
|
|
|
202
201
|
request.parse = {
|
|
203
202
|
'application/x-www-form-urlencoded': parseString,
|
|
204
|
-
'application/json': JSON.parse
|
|
203
|
+
'application/json': JSON.parse
|
|
205
204
|
};
|
|
206
205
|
|
|
207
206
|
/**
|
|
@@ -244,7 +243,9 @@ function parseHeader(str) {
|
|
|
244
243
|
*/
|
|
245
244
|
|
|
246
245
|
function isJSON(mime) {
|
|
247
|
-
|
|
246
|
+
// should match /json or +json
|
|
247
|
+
// but not /json-seq
|
|
248
|
+
return /[\/+]json($|[^-\w])/.test(mime);
|
|
248
249
|
}
|
|
249
250
|
|
|
250
251
|
/**
|
|
@@ -595,8 +596,7 @@ Request.prototype._getFormData = function(){
|
|
|
595
596
|
*/
|
|
596
597
|
|
|
597
598
|
Request.prototype.callback = function(err, res){
|
|
598
|
-
|
|
599
|
-
if (this._maxRetries && this._retries++ < this._maxRetries && shouldRetry(err, res)) {
|
|
599
|
+
if (this._shouldRetry(err, res)) {
|
|
600
600
|
return this._retry();
|
|
601
601
|
}
|
|
602
602
|
|