axios 1.15.0 → 1.15.2
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/CHANGELOG.md +234 -0
- package/README.md +240 -204
- package/dist/axios.js +124 -72
- package/dist/axios.js.map +1 -1
- package/dist/axios.min.js +2 -2
- package/dist/axios.min.js.map +1 -1
- package/dist/browser/axios.cjs +170 -105
- package/dist/browser/axios.cjs.map +1 -1
- package/dist/esm/axios.js +170 -105
- package/dist/esm/axios.js.map +1 -1
- package/dist/esm/axios.min.js +2 -2
- package/dist/esm/axios.min.js.map +1 -1
- package/dist/node/axios.cjs +278 -100
- package/dist/node/axios.cjs.map +1 -1
- package/index.d.cts +15 -28
- package/index.d.ts +133 -226
- package/lib/adapters/fetch.js +21 -6
- package/lib/adapters/http.js +146 -17
- package/lib/core/AxiosError.js +34 -33
- package/lib/core/AxiosHeaders.js +24 -25
- package/lib/core/buildFullPath.js +1 -1
- package/lib/core/mergeConfig.js +18 -4
- package/lib/defaults/index.js +13 -8
- package/lib/env/data.js +1 -1
- package/lib/helpers/AxiosURLSearchParams.js +1 -2
- package/lib/helpers/formDataToJSON.js +3 -1
- package/lib/helpers/formDataToStream.js +2 -1
- package/lib/helpers/progressEventReducer.js +5 -5
- package/lib/helpers/resolveConfig.js +25 -5
- package/lib/helpers/shouldBypassProxy.js +48 -1
- package/lib/helpers/toFormData.js +10 -2
- package/lib/helpers/validator.js +3 -1
- package/lib/utils.js +10 -10
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<h3 align="center"> 💎 Platinum sponsors <br> </h3> <table align="center"><tr><td align="center" width="50%"> <a href="https://thanks.dev/?utm_source=axios&utm_medium=sponsorlist&utm_campaign=sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <img width="90px" height="90px" src="https://axios-http.com/assets/sponsors/opencollective/ed51c2ee8f1b70aa3484d6dd678652134079a036.png" alt="THANKS.DEV"/> </a> <p align="center" title="We're passionate about making open source sustainable. Scan your dependancy tree to better understand which open source projects need funding the most. Maintainers can also register their projects to become eligible for funding.">We're passionate about making open source sustainable. Scan your dependancy tree to better understand which open source projects need funding the...</p> <p align="center"> <a href="https://thanks.dev/?utm_source=axios&utm_medium=readme_sponsorlist&utm_campaign=sponsorship" target="_blank"><b>thanks.dev</b></a> </p>
|
|
2
|
-
</td><td align="center" width="50%"> <a href="https://opencollective.com/hopper-security?utm_source=axios&utm_medium=sponsorlist&utm_campaign=sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <img width="90px" height="90px" src="https://axios-http.com/assets/sponsors/opencollective/180d02a83ee99448f850e39eed6dbb95f56000ba.png" alt="Hopper Security"/> </a> <p align="center"> </p>
|
|
2
|
+
</td><td align="center" width="50%"> <a href="https://opencollective.com/hopper-security?utm_source=axios&utm_medium=sponsorlist&utm_campaign=sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <img width="90px" height="90px" src="https://axios-http.com/assets/sponsors/opencollective/180d02a83ee99448f850e39eed6dbb95f56000ba.png" alt="Hopper Security"/> </a> <p align="center">Hopper provides a secure open-source registry where every component is verified against malware and continuously remediated for vulnerabilities across any version. In simple terms, Hopper removes the need to manage software supply chain risk altogether.</p><p align="center"> <a href="https://hopper.security/?utm_source=axios&utm_medium=readme_sponsorlist&utm_campaign=sponsorship" target="_blank"><b>Hopper.Security</b></a> </p>
|
|
3
3
|
</td></tr></table><table align="center"><tr><td align="center" width="50%"> <a href="https://opencollective.com/axios/contribute" target="_blank" >💜 Become a sponsor</a>
|
|
4
4
|
</td><td align="center" width="50%"> <a href="https://opencollective.com/axios/contribute" target="_blank" >💜 Become a sponsor</a>
|
|
5
5
|
</td></tr></table>
|
|
@@ -92,6 +92,8 @@
|
|
|
92
92
|
- [Semver](#semver)
|
|
93
93
|
- [Promises](#promises)
|
|
94
94
|
- [TypeScript](#typescript)
|
|
95
|
+
- [Contributing](#contributing)
|
|
96
|
+
- [Local setup](#local-setup)
|
|
95
97
|
- [Resources](#resources)
|
|
96
98
|
- [Credits](#credits)
|
|
97
99
|
- [License](#license)
|
|
@@ -127,12 +129,6 @@ Using npm:
|
|
|
127
129
|
$ npm install axios
|
|
128
130
|
```
|
|
129
131
|
|
|
130
|
-
Using bower:
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
$ bower install axios
|
|
134
|
-
```
|
|
135
|
-
|
|
136
132
|
Using yarn:
|
|
137
133
|
|
|
138
134
|
```bash
|
|
@@ -154,36 +150,36 @@ $ bun add axios
|
|
|
154
150
|
Once the package is installed, you can import the library using `import` or `require` approach:
|
|
155
151
|
|
|
156
152
|
```js
|
|
157
|
-
import axios, { isCancel, AxiosError } from
|
|
153
|
+
import axios, { isCancel, AxiosError } from 'axios';
|
|
158
154
|
```
|
|
159
155
|
|
|
160
156
|
You can also use the default export, since the named export is just a re-export from the Axios factory:
|
|
161
157
|
|
|
162
158
|
```js
|
|
163
|
-
import axios from
|
|
159
|
+
import axios from 'axios';
|
|
164
160
|
|
|
165
|
-
console.log(axios.isCancel(
|
|
161
|
+
console.log(axios.isCancel('something'));
|
|
166
162
|
```
|
|
167
163
|
|
|
168
164
|
If you use `require` for importing, **only the default export is available**:
|
|
169
165
|
|
|
170
166
|
```js
|
|
171
|
-
const axios = require(
|
|
167
|
+
const axios = require('axios');
|
|
172
168
|
|
|
173
|
-
console.log(axios.isCancel(
|
|
169
|
+
console.log(axios.isCancel('something'));
|
|
174
170
|
```
|
|
175
171
|
|
|
176
172
|
For some bundlers and some ES6 linters you may need to do the following:
|
|
177
173
|
|
|
178
174
|
```js
|
|
179
|
-
import { default as axios } from
|
|
175
|
+
import { default as axios } from 'axios';
|
|
180
176
|
```
|
|
181
177
|
|
|
182
178
|
For cases where something went wrong when trying to import a module into a custom or legacy environment,
|
|
183
179
|
you can try importing the module package directly:
|
|
184
180
|
|
|
185
181
|
```js
|
|
186
|
-
const axios = require(
|
|
182
|
+
const axios = require('axios/dist/browser/axios.cjs'); // browser commonJS bundle (ES2017)
|
|
187
183
|
// const axios = require('axios/dist/node/axios.cjs'); // node commonJS bundle (ES2017)
|
|
188
184
|
```
|
|
189
185
|
|
|
@@ -204,11 +200,11 @@ Using unpkg CDN:
|
|
|
204
200
|
## Example
|
|
205
201
|
|
|
206
202
|
```js
|
|
207
|
-
import axios from
|
|
203
|
+
import axios from 'axios';
|
|
208
204
|
//const axios = require('axios'); // legacy way
|
|
209
205
|
|
|
210
206
|
try {
|
|
211
|
-
const response = await axios.get(
|
|
207
|
+
const response = await axios.get('/user?ID=12345');
|
|
212
208
|
console.log(response);
|
|
213
209
|
} catch (error) {
|
|
214
210
|
console.error(error);
|
|
@@ -216,7 +212,7 @@ try {
|
|
|
216
212
|
|
|
217
213
|
// Optionally the request above could also be done as
|
|
218
214
|
axios
|
|
219
|
-
.get(
|
|
215
|
+
.get('/user', {
|
|
220
216
|
params: {
|
|
221
217
|
ID: 12345,
|
|
222
218
|
},
|
|
@@ -234,7 +230,7 @@ axios
|
|
|
234
230
|
// Want to use async/await? Add the `async` keyword to your outer function/method.
|
|
235
231
|
async function getUser() {
|
|
236
232
|
try {
|
|
237
|
-
const response = await axios.get(
|
|
233
|
+
const response = await axios.get('/user?ID=12345');
|
|
238
234
|
console.log(response);
|
|
239
235
|
} catch (error) {
|
|
240
236
|
console.error(error);
|
|
@@ -248,9 +244,9 @@ async function getUser() {
|
|
|
248
244
|
Performing a `POST` request
|
|
249
245
|
|
|
250
246
|
```js
|
|
251
|
-
const response = await axios.post(
|
|
252
|
-
firstName:
|
|
253
|
-
lastName:
|
|
247
|
+
const response = await axios.post('/user', {
|
|
248
|
+
firstName: 'Fred',
|
|
249
|
+
lastName: 'Flintstone',
|
|
254
250
|
});
|
|
255
251
|
console.log(response);
|
|
256
252
|
```
|
|
@@ -259,11 +255,11 @@ Performing multiple concurrent requests
|
|
|
259
255
|
|
|
260
256
|
```js
|
|
261
257
|
function getUserAccount() {
|
|
262
|
-
return axios.get(
|
|
258
|
+
return axios.get('/user/12345');
|
|
263
259
|
}
|
|
264
260
|
|
|
265
261
|
function getUserPermissions() {
|
|
266
|
-
return axios.get(
|
|
262
|
+
return axios.get('/user/12345/permissions');
|
|
267
263
|
}
|
|
268
264
|
|
|
269
265
|
Promise.all([getUserAccount(), getUserPermissions()]).then(function (results) {
|
|
@@ -281,11 +277,11 @@ Requests can be made by passing the relevant config to `axios`.
|
|
|
281
277
|
```js
|
|
282
278
|
// Send a POST request
|
|
283
279
|
axios({
|
|
284
|
-
method:
|
|
285
|
-
url:
|
|
280
|
+
method: 'post',
|
|
281
|
+
url: '/user/12345',
|
|
286
282
|
data: {
|
|
287
|
-
firstName:
|
|
288
|
-
lastName:
|
|
283
|
+
firstName: 'Fred',
|
|
284
|
+
lastName: 'Flintstone',
|
|
289
285
|
},
|
|
290
286
|
});
|
|
291
287
|
```
|
|
@@ -293,18 +289,18 @@ axios({
|
|
|
293
289
|
```js
|
|
294
290
|
// GET request for remote image in node.js
|
|
295
291
|
const response = await axios({
|
|
296
|
-
method:
|
|
297
|
-
url:
|
|
298
|
-
responseType:
|
|
292
|
+
method: 'get',
|
|
293
|
+
url: 'https://bit.ly/2mTM3nY',
|
|
294
|
+
responseType: 'stream',
|
|
299
295
|
});
|
|
300
|
-
response.data.pipe(fs.createWriteStream(
|
|
296
|
+
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'));
|
|
301
297
|
```
|
|
302
298
|
|
|
303
299
|
##### axios(url[, config])
|
|
304
300
|
|
|
305
301
|
```js
|
|
306
302
|
// Send a GET request (default method)
|
|
307
|
-
axios(
|
|
303
|
+
axios('/user/12345');
|
|
308
304
|
```
|
|
309
305
|
|
|
310
306
|
### Request method aliases
|
|
@@ -348,9 +344,9 @@ You can create a new instance of axios with a custom config.
|
|
|
348
344
|
|
|
349
345
|
```js
|
|
350
346
|
const instance = axios.create({
|
|
351
|
-
baseURL:
|
|
347
|
+
baseURL: 'https://some-domain.com/api/',
|
|
352
348
|
timeout: 1000,
|
|
353
|
-
headers: {
|
|
349
|
+
headers: { 'X-Custom-Header': 'foobar' },
|
|
354
350
|
});
|
|
355
351
|
```
|
|
356
352
|
|
|
@@ -378,6 +374,19 @@ The available instance methods are listed below. The specified config will be me
|
|
|
378
374
|
|
|
379
375
|
## Request Config
|
|
380
376
|
|
|
377
|
+
### ⚠️ Security notice: decompression-bomb protection is opt-in
|
|
378
|
+
|
|
379
|
+
By default `maxContentLength` and `maxBodyLength` are `-1` (unlimited). A malicious or compromised server can return a tiny gzip/deflate/brotli body that expands to gigabytes and exhaust the Node.js process.
|
|
380
|
+
|
|
381
|
+
If you call servers you do not fully trust, **set a cap**:
|
|
382
|
+
|
|
383
|
+
```js
|
|
384
|
+
axios.defaults.maxContentLength = 10 * 1024 * 1024; // 10 MB
|
|
385
|
+
axios.defaults.maxBodyLength = 10 * 1024 * 1024;
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
See the [security guide](https://axios.rest/pages/misc/security.html) for details.
|
|
389
|
+
|
|
381
390
|
These are the available config options for making requests. Only the `url` is required. Requests will default to `GET` if `method` is not specified.
|
|
382
391
|
|
|
383
392
|
```js
|
|
@@ -436,7 +445,12 @@ These are the available config options for making requests. Only the `url` is re
|
|
|
436
445
|
serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ),
|
|
437
446
|
|
|
438
447
|
// Configuration for formatting array indexes in the params.
|
|
439
|
-
indexes: false // Three available options: (1) indexes: null (leads to no brackets), (2) (default) indexes: false (leads to empty brackets), (3) indexes: true (leads to brackets with indexes).
|
|
448
|
+
indexes: false, // Three available options: (1) indexes: null (leads to no brackets), (2) (default) indexes: false (leads to empty brackets), (3) indexes: true (leads to brackets with indexes).
|
|
449
|
+
|
|
450
|
+
// Maximum object nesting depth when serializing params. Payloads deeper than this throw an
|
|
451
|
+
// AxiosError with code ERR_FORM_DATA_DEPTH_EXCEEDED. Default: 100. Set to Infinity to disable.
|
|
452
|
+
maxDepth: 100
|
|
453
|
+
|
|
440
454
|
},
|
|
441
455
|
|
|
442
456
|
// `data` is the data to be sent as the request body
|
|
@@ -586,8 +600,19 @@ These are the available config options for making requests. Only the `url` is re
|
|
|
586
600
|
// e.g. '/var/run/docker.sock' to send requests to the docker daemon.
|
|
587
601
|
// Only either `socketPath` or `proxy` can be specified.
|
|
588
602
|
// If both are specified, `socketPath` is used.
|
|
603
|
+
//
|
|
604
|
+
// Security: when `socketPath` is set, hostname/port of the URL are ignored,
|
|
605
|
+
// which bypasses hostname-based SSRF protections. Never derive `socketPath`
|
|
606
|
+
// from untrusted input. Use `allowedSocketPaths` (below) to restrict accepted
|
|
607
|
+
// socket paths for defense-in-depth.
|
|
589
608
|
socketPath: null, // default
|
|
590
609
|
|
|
610
|
+
// `allowedSocketPaths` restricts which `socketPath` values are accepted.
|
|
611
|
+
// Accepts a string or array of strings. Entries and the incoming socketPath
|
|
612
|
+
// are compared after path.resolve(). A mismatch throws AxiosError with code
|
|
613
|
+
// `ERR_BAD_OPTION_VALUE`. When null/undefined, no restriction is applied.
|
|
614
|
+
allowedSocketPaths: null, // default
|
|
615
|
+
|
|
591
616
|
// `transport` determines the transport method that will be used to make the request.
|
|
592
617
|
// If defined, it will be used. Otherwise, if `maxRedirects` is 0,
|
|
593
618
|
// the default `http` or `https` library will be used, depending on the protocol specified in `protocol`.
|
|
@@ -679,6 +704,7 @@ These are the available config options for making requests. Only the `url` is re
|
|
|
679
704
|
dots: boolean; // use dots instead of brackets format
|
|
680
705
|
metaTokens: boolean; // keep special endings like {} in parameter key
|
|
681
706
|
indexes: boolean; // array indexes format null - no brackets, false - empty brackets, true - brackets with indexes
|
|
707
|
+
maxDepth: 100; // maximum object nesting depth; throws AxiosError (ERR_FORM_DATA_DEPTH_EXCEEDED) if exceeded. Set to Infinity to disable.
|
|
682
708
|
},
|
|
683
709
|
|
|
684
710
|
// http adapter only (node.js)
|
|
@@ -688,6 +714,7 @@ These are the available config options for making requests. Only the `url` is re
|
|
|
688
714
|
]
|
|
689
715
|
}
|
|
690
716
|
```
|
|
717
|
+
|
|
691
718
|
## 🔥 HTTP/2 Support
|
|
692
719
|
|
|
693
720
|
Axios has experimental HTTP/2 support available via the Node.js HTTP adapter.
|
|
@@ -731,7 +758,7 @@ The response to a request contains the following information.
|
|
|
731
758
|
When using `then`, you will receive the response as follows:
|
|
732
759
|
|
|
733
760
|
```js
|
|
734
|
-
const response = await axios.get(
|
|
761
|
+
const response = await axios.get('/user/12345');
|
|
735
762
|
console.log(response.data);
|
|
736
763
|
console.log(response.status);
|
|
737
764
|
console.log(response.statusText);
|
|
@@ -748,14 +775,13 @@ You can specify config defaults that will be applied to every request.
|
|
|
748
775
|
### Global axios defaults
|
|
749
776
|
|
|
750
777
|
```js
|
|
751
|
-
axios.defaults.baseURL =
|
|
778
|
+
axios.defaults.baseURL = 'https://api.example.com';
|
|
752
779
|
|
|
753
780
|
// Important: If axios is used with multiple domains, the AUTH_TOKEN will be sent to all of them.
|
|
754
781
|
// See below for an example using Custom instance defaults instead.
|
|
755
|
-
axios.defaults.headers.common[
|
|
782
|
+
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
|
|
756
783
|
|
|
757
|
-
axios.defaults.headers.post[
|
|
758
|
-
"application/x-www-form-urlencoded";
|
|
784
|
+
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
759
785
|
```
|
|
760
786
|
|
|
761
787
|
### Custom instance defaults
|
|
@@ -763,11 +789,11 @@ axios.defaults.headers.post["Content-Type"] =
|
|
|
763
789
|
```js
|
|
764
790
|
// Set config defaults when creating the instance
|
|
765
791
|
const instance = axios.create({
|
|
766
|
-
baseURL:
|
|
792
|
+
baseURL: 'https://api.example.com',
|
|
767
793
|
});
|
|
768
794
|
|
|
769
795
|
// Alter defaults after instance has been created
|
|
770
|
-
instance.defaults.headers.common[
|
|
796
|
+
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
|
|
771
797
|
```
|
|
772
798
|
|
|
773
799
|
### Config order of precedence
|
|
@@ -784,7 +810,7 @@ const instance = axios.create();
|
|
|
784
810
|
instance.defaults.timeout = 2500;
|
|
785
811
|
|
|
786
812
|
// Override timeout for this request as it's known to take a long time
|
|
787
|
-
instance.get(
|
|
813
|
+
instance.get('/longRequest', {
|
|
788
814
|
timeout: 5000,
|
|
789
815
|
});
|
|
790
816
|
```
|
|
@@ -806,7 +832,7 @@ instance.interceptors.request.use(
|
|
|
806
832
|
function (error) {
|
|
807
833
|
// Do something with the request error
|
|
808
834
|
return Promise.reject(error);
|
|
809
|
-
}
|
|
835
|
+
}
|
|
810
836
|
);
|
|
811
837
|
|
|
812
838
|
// Add a response interceptor
|
|
@@ -820,7 +846,7 @@ instance.interceptors.response.use(
|
|
|
820
846
|
// Any status codes that fall outside the range of 2xx cause this function to trigger
|
|
821
847
|
// Do something with response error
|
|
822
848
|
return Promise.reject(error);
|
|
823
|
-
}
|
|
849
|
+
}
|
|
824
850
|
);
|
|
825
851
|
```
|
|
826
852
|
|
|
@@ -865,11 +891,11 @@ to the options object that will tell axios to run the code synchronously and avo
|
|
|
865
891
|
```js
|
|
866
892
|
axios.interceptors.request.use(
|
|
867
893
|
function (config) {
|
|
868
|
-
config.headers.test =
|
|
894
|
+
config.headers.test = 'I am only a header!';
|
|
869
895
|
return config;
|
|
870
896
|
},
|
|
871
897
|
null,
|
|
872
|
-
{ synchronous: true }
|
|
898
|
+
{ synchronous: true }
|
|
873
899
|
);
|
|
874
900
|
```
|
|
875
901
|
|
|
@@ -881,15 +907,15 @@ asynchronous request interceptor that only needs to run at certain times.
|
|
|
881
907
|
|
|
882
908
|
```js
|
|
883
909
|
function onGetCall(config) {
|
|
884
|
-
return config.method ===
|
|
910
|
+
return config.method === 'get';
|
|
885
911
|
}
|
|
886
912
|
axios.interceptors.request.use(
|
|
887
913
|
function (config) {
|
|
888
|
-
config.headers.test =
|
|
914
|
+
config.headers.test = 'special get headers';
|
|
889
915
|
return config;
|
|
890
916
|
},
|
|
891
917
|
null,
|
|
892
|
-
{ runWhen: onGetCall }
|
|
918
|
+
{ runWhen: onGetCall }
|
|
893
919
|
);
|
|
894
920
|
```
|
|
895
921
|
|
|
@@ -913,12 +939,12 @@ const interceptor = (id) => (base) => {
|
|
|
913
939
|
return base;
|
|
914
940
|
};
|
|
915
941
|
|
|
916
|
-
instance.interceptors.request.use(interceptor(
|
|
917
|
-
instance.interceptors.request.use(interceptor(
|
|
918
|
-
instance.interceptors.request.use(interceptor(
|
|
919
|
-
instance.interceptors.response.use(interceptor(
|
|
920
|
-
instance.interceptors.response.use(interceptor(
|
|
921
|
-
instance.interceptors.response.use(interceptor(
|
|
942
|
+
instance.interceptors.request.use(interceptor('Request Interceptor 1'));
|
|
943
|
+
instance.interceptors.request.use(interceptor('Request Interceptor 2'));
|
|
944
|
+
instance.interceptors.request.use(interceptor('Request Interceptor 3'));
|
|
945
|
+
instance.interceptors.response.use(interceptor('Response Interceptor 1'));
|
|
946
|
+
instance.interceptors.response.use(interceptor('Response Interceptor 2'));
|
|
947
|
+
instance.interceptors.response.use(interceptor('Response Interceptor 3'));
|
|
922
948
|
|
|
923
949
|
// Console output:
|
|
924
950
|
// Request Interceptor 3
|
|
@@ -982,7 +1008,7 @@ Below is a list of potential axios identified error:
|
|
|
982
1008
|
The default behavior is to reject every response that returns with a status code that falls out of the range of 2xx and treat it as an error.
|
|
983
1009
|
|
|
984
1010
|
```js
|
|
985
|
-
axios.get(
|
|
1011
|
+
axios.get('/user/12345').catch(function (error) {
|
|
986
1012
|
if (error.response) {
|
|
987
1013
|
// The request was made and the server responded with a status code
|
|
988
1014
|
// that falls out of the range of 2xx
|
|
@@ -996,7 +1022,7 @@ axios.get("/user/12345").catch(function (error) {
|
|
|
996
1022
|
console.log(error.request);
|
|
997
1023
|
} else {
|
|
998
1024
|
// Something happened in setting up the request that triggered an Error
|
|
999
|
-
console.log(
|
|
1025
|
+
console.log('Error', error.message);
|
|
1000
1026
|
}
|
|
1001
1027
|
console.log(error.config);
|
|
1002
1028
|
});
|
|
@@ -1005,7 +1031,7 @@ axios.get("/user/12345").catch(function (error) {
|
|
|
1005
1031
|
Using the `validateStatus` config option, you can override the default condition (status >= 200 && status < 300) and define HTTP code(s) that should throw an error.
|
|
1006
1032
|
|
|
1007
1033
|
```js
|
|
1008
|
-
axios.get(
|
|
1034
|
+
axios.get('/user/12345', {
|
|
1009
1035
|
validateStatus: function (status) {
|
|
1010
1036
|
return status < 500; // Resolve only if the status code is less than 500
|
|
1011
1037
|
},
|
|
@@ -1015,7 +1041,7 @@ axios.get("/user/12345", {
|
|
|
1015
1041
|
Using `toJSON` you get an object with more information about the HTTP error.
|
|
1016
1042
|
|
|
1017
1043
|
```js
|
|
1018
|
-
axios.get(
|
|
1044
|
+
axios.get('/user/12345').catch(function (error) {
|
|
1019
1045
|
console.log(error.toJSON());
|
|
1020
1046
|
});
|
|
1021
1047
|
```
|
|
@@ -1025,7 +1051,7 @@ axios.get("/user/12345").catch(function (error) {
|
|
|
1025
1051
|
```js
|
|
1026
1052
|
async function fetchWithTimeout() {
|
|
1027
1053
|
try {
|
|
1028
|
-
const response = await axios.get(
|
|
1054
|
+
const response = await axios.get('https://example.com/data', {
|
|
1029
1055
|
timeout: 5000, // 5 seconds
|
|
1030
1056
|
transitional: {
|
|
1031
1057
|
// set to true if you prefer ETIMEDOUT over ECONNABORTED
|
|
@@ -1033,19 +1059,19 @@ async function fetchWithTimeout() {
|
|
|
1033
1059
|
},
|
|
1034
1060
|
});
|
|
1035
1061
|
|
|
1036
|
-
console.log(
|
|
1062
|
+
console.log('Response:', response.data);
|
|
1037
1063
|
} catch (error) {
|
|
1038
1064
|
if (axios.isAxiosError(error)) {
|
|
1039
|
-
if (error.code ===
|
|
1040
|
-
console.error(
|
|
1065
|
+
if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') {
|
|
1066
|
+
console.error('Request timed out. Please try again.');
|
|
1041
1067
|
return;
|
|
1042
1068
|
}
|
|
1043
1069
|
|
|
1044
|
-
console.error(
|
|
1070
|
+
console.error('Axios error:', error.message);
|
|
1045
1071
|
return;
|
|
1046
1072
|
}
|
|
1047
1073
|
|
|
1048
|
-
console.error(
|
|
1074
|
+
console.error('Unexpected error:', error);
|
|
1049
1075
|
}
|
|
1050
1076
|
}
|
|
1051
1077
|
```
|
|
@@ -1060,7 +1086,7 @@ Starting from `v0.22.0` Axios supports AbortController to cancel requests in a f
|
|
|
1060
1086
|
const controller = new AbortController();
|
|
1061
1087
|
|
|
1062
1088
|
axios
|
|
1063
|
-
.get(
|
|
1089
|
+
.get('/foo/bar', {
|
|
1064
1090
|
signal: controller.signal,
|
|
1065
1091
|
})
|
|
1066
1092
|
.then(function (response) {
|
|
@@ -1085,29 +1111,29 @@ const CancelToken = axios.CancelToken;
|
|
|
1085
1111
|
const source = CancelToken.source();
|
|
1086
1112
|
|
|
1087
1113
|
axios
|
|
1088
|
-
.get(
|
|
1114
|
+
.get('/user/12345', {
|
|
1089
1115
|
cancelToken: source.token,
|
|
1090
1116
|
})
|
|
1091
1117
|
.catch(function (thrown) {
|
|
1092
1118
|
if (axios.isCancel(thrown)) {
|
|
1093
|
-
console.log(
|
|
1119
|
+
console.log('Request canceled', thrown.message);
|
|
1094
1120
|
} else {
|
|
1095
1121
|
// handle error
|
|
1096
1122
|
}
|
|
1097
1123
|
});
|
|
1098
1124
|
|
|
1099
1125
|
axios.post(
|
|
1100
|
-
|
|
1126
|
+
'/user/12345',
|
|
1101
1127
|
{
|
|
1102
|
-
name:
|
|
1128
|
+
name: 'new name',
|
|
1103
1129
|
},
|
|
1104
1130
|
{
|
|
1105
1131
|
cancelToken: source.token,
|
|
1106
|
-
}
|
|
1132
|
+
}
|
|
1107
1133
|
);
|
|
1108
1134
|
|
|
1109
1135
|
// cancel the request (the message parameter is optional)
|
|
1110
|
-
source.cancel(
|
|
1136
|
+
source.cancel('Operation canceled by the user.');
|
|
1111
1137
|
```
|
|
1112
1138
|
|
|
1113
1139
|
You can also create a cancel token by passing an executor function to the `CancelToken` constructor:
|
|
@@ -1116,7 +1142,7 @@ You can also create a cancel token by passing an executor function to the `Cance
|
|
|
1116
1142
|
const CancelToken = axios.CancelToken;
|
|
1117
1143
|
let cancel;
|
|
1118
1144
|
|
|
1119
|
-
axios.get(
|
|
1145
|
+
axios.get('/user/12345', {
|
|
1120
1146
|
cancelToken: new CancelToken(function executor(c) {
|
|
1121
1147
|
// An executor function receives a cancel function as a parameter
|
|
1122
1148
|
cancel = c;
|
|
@@ -1139,9 +1165,9 @@ cancel();
|
|
|
1139
1165
|
By default, axios serializes JavaScript objects to `JSON`. To send data in the [`application/x-www-form-urlencoded`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) format instead, you can use the [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) API, which is [supported](http://www.caniuse.com/#feat=urlsearchparams) in the vast majority of browsers, and [Node](https://nodejs.org/api/url.html#url_class_urlsearchparams) starting with v10 (released in 2018).
|
|
1140
1166
|
|
|
1141
1167
|
```js
|
|
1142
|
-
const params = new URLSearchParams({ foo:
|
|
1143
|
-
params.append(
|
|
1144
|
-
axios.post(
|
|
1168
|
+
const params = new URLSearchParams({ foo: 'bar' });
|
|
1169
|
+
params.append('extraparam', 'value');
|
|
1170
|
+
axios.post('/foo', params);
|
|
1145
1171
|
```
|
|
1146
1172
|
|
|
1147
1173
|
### Query string (Older browsers)
|
|
@@ -1151,18 +1177,18 @@ For compatibility with very old browsers, there is a [polyfill](https://github.c
|
|
|
1151
1177
|
Alternatively, you can encode data using the [`qs`](https://github.com/ljharb/qs) library:
|
|
1152
1178
|
|
|
1153
1179
|
```js
|
|
1154
|
-
const qs = require(
|
|
1155
|
-
axios.post(
|
|
1180
|
+
const qs = require('qs');
|
|
1181
|
+
axios.post('/foo', qs.stringify({ bar: 123 }));
|
|
1156
1182
|
```
|
|
1157
1183
|
|
|
1158
1184
|
Or in another way (ES6),
|
|
1159
1185
|
|
|
1160
1186
|
```js
|
|
1161
|
-
import qs from
|
|
1187
|
+
import qs from 'qs';
|
|
1162
1188
|
const data = { bar: 123 };
|
|
1163
1189
|
const options = {
|
|
1164
|
-
method:
|
|
1165
|
-
headers: {
|
|
1190
|
+
method: 'POST',
|
|
1191
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
1166
1192
|
data: qs.stringify(data),
|
|
1167
1193
|
url,
|
|
1168
1194
|
};
|
|
@@ -1174,8 +1200,8 @@ axios(options);
|
|
|
1174
1200
|
For older Node.js engines, you can use the [`querystring`](https://nodejs.org/api/querystring.html) module as follows:
|
|
1175
1201
|
|
|
1176
1202
|
```js
|
|
1177
|
-
const querystring = require(
|
|
1178
|
-
axios.post(
|
|
1203
|
+
const querystring = require('querystring');
|
|
1204
|
+
axios.post('https://something.com/', querystring.stringify({ foo: 'bar' }));
|
|
1179
1205
|
```
|
|
1180
1206
|
|
|
1181
1207
|
You can also use the [`qs`](https://github.com/ljharb/qs) library.
|
|
@@ -1192,13 +1218,13 @@ const data = {
|
|
|
1192
1218
|
arr: [1, 2, 3],
|
|
1193
1219
|
arr2: [1, [2], 3],
|
|
1194
1220
|
users: [
|
|
1195
|
-
{ name:
|
|
1196
|
-
{ name:
|
|
1221
|
+
{ name: 'Peter', surname: 'Griffin' },
|
|
1222
|
+
{ name: 'Thomas', surname: 'Anderson' },
|
|
1197
1223
|
],
|
|
1198
1224
|
};
|
|
1199
1225
|
|
|
1200
|
-
await axios.postForm(
|
|
1201
|
-
headers: {
|
|
1226
|
+
await axios.postForm('https://postman-echo.com/post', data, {
|
|
1227
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
1202
1228
|
});
|
|
1203
1229
|
```
|
|
1204
1230
|
|
|
@@ -1226,7 +1252,7 @@ const app = express();
|
|
|
1226
1252
|
|
|
1227
1253
|
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
|
|
1228
1254
|
|
|
1229
|
-
app.post(
|
|
1255
|
+
app.post('/', function (req, res, next) {
|
|
1230
1256
|
// echo body as JSON
|
|
1231
1257
|
res.send(JSON.stringify(req.body));
|
|
1232
1258
|
});
|
|
@@ -1243,22 +1269,22 @@ Setting the `Content-Type` header is not required as Axios guesses it based on t
|
|
|
1243
1269
|
|
|
1244
1270
|
```js
|
|
1245
1271
|
const formData = new FormData();
|
|
1246
|
-
formData.append(
|
|
1272
|
+
formData.append('foo', 'bar');
|
|
1247
1273
|
|
|
1248
|
-
axios.post(
|
|
1274
|
+
axios.post('https://httpbin.org/post', formData);
|
|
1249
1275
|
```
|
|
1250
1276
|
|
|
1251
1277
|
In node.js, you can use the [`form-data`](https://github.com/form-data/form-data) library as follows:
|
|
1252
1278
|
|
|
1253
1279
|
```js
|
|
1254
|
-
const FormData = require(
|
|
1280
|
+
const FormData = require('form-data');
|
|
1255
1281
|
|
|
1256
1282
|
const form = new FormData();
|
|
1257
|
-
form.append(
|
|
1258
|
-
form.append(
|
|
1259
|
-
form.append(
|
|
1283
|
+
form.append('my_field', 'my value');
|
|
1284
|
+
form.append('my_buffer', Buffer.alloc(10));
|
|
1285
|
+
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
|
|
1260
1286
|
|
|
1261
|
-
axios.post(
|
|
1287
|
+
axios.post('https://example.com', form);
|
|
1262
1288
|
```
|
|
1263
1289
|
|
|
1264
1290
|
### 🆕 Automatic serialization to FormData
|
|
@@ -1269,17 +1295,17 @@ header is set to `multipart/form-data`.
|
|
|
1269
1295
|
The following request will submit the data in a FormData format (Browser & Node.js):
|
|
1270
1296
|
|
|
1271
1297
|
```js
|
|
1272
|
-
import axios from
|
|
1298
|
+
import axios from 'axios';
|
|
1273
1299
|
|
|
1274
1300
|
axios
|
|
1275
1301
|
.post(
|
|
1276
|
-
|
|
1302
|
+
'https://httpbin.org/post',
|
|
1277
1303
|
{ x: 1 },
|
|
1278
1304
|
{
|
|
1279
1305
|
headers: {
|
|
1280
|
-
|
|
1306
|
+
'Content-Type': 'multipart/form-data',
|
|
1281
1307
|
},
|
|
1282
|
-
}
|
|
1308
|
+
}
|
|
1283
1309
|
)
|
|
1284
1310
|
.then(({ data }) => console.log(data));
|
|
1285
1311
|
```
|
|
@@ -1290,18 +1316,18 @@ You can overload the FormData class by setting the `env.FormData` config variabl
|
|
|
1290
1316
|
but you probably won't need it in most cases:
|
|
1291
1317
|
|
|
1292
1318
|
```js
|
|
1293
|
-
const axios = require(
|
|
1294
|
-
var FormData = require(
|
|
1319
|
+
const axios = require('axios');
|
|
1320
|
+
var FormData = require('form-data');
|
|
1295
1321
|
|
|
1296
1322
|
axios
|
|
1297
1323
|
.post(
|
|
1298
|
-
|
|
1324
|
+
'https://httpbin.org/post',
|
|
1299
1325
|
{ x: 1, buf: Buffer.alloc(10) },
|
|
1300
1326
|
{
|
|
1301
1327
|
headers: {
|
|
1302
|
-
|
|
1328
|
+
'Content-Type': 'multipart/form-data',
|
|
1303
1329
|
},
|
|
1304
|
-
}
|
|
1330
|
+
}
|
|
1305
1331
|
)
|
|
1306
1332
|
.then(({ data }) => console.log(data));
|
|
1307
1333
|
```
|
|
@@ -1327,6 +1353,18 @@ FormData serializer supports additional options via `config.formSerializer: obje
|
|
|
1327
1353
|
- `null` - don't add brackets (`arr: 1`, `arr: 2`, `arr: 3`)
|
|
1328
1354
|
- `false`(default) - add empty brackets (`arr[]: 1`, `arr[]: 2`, `arr[]: 3`)
|
|
1329
1355
|
- `true` - add brackets with indexes (`arr[0]: 1`, `arr[1]: 2`, `arr[2]: 3`)
|
|
1356
|
+
- `maxDepth: number = 100` - maximum object nesting depth the serializer will recurse into. If the
|
|
1357
|
+
input object exceeds this depth, an `AxiosError` with `code: 'ERR_FORM_DATA_DEPTH_EXCEEDED'` is
|
|
1358
|
+
thrown instead of overflowing the call stack. This protects server-side applications from DoS
|
|
1359
|
+
attacks via deeply nested payloads. Set to `Infinity` to disable the limit and restore pre-fix behaviour.
|
|
1360
|
+
|
|
1361
|
+
```js
|
|
1362
|
+
// Raise the limit for a schema that genuinely nests deeper than 100 levels:
|
|
1363
|
+
axios.postForm('/api', data, { formSerializer: { maxDepth: 200 } });
|
|
1364
|
+
|
|
1365
|
+
// Same protection applies to params serialization:
|
|
1366
|
+
axios.get('/api', { params: data, paramsSerializer: { maxDepth: 200 } });
|
|
1367
|
+
```
|
|
1330
1368
|
|
|
1331
1369
|
Let's say we have an object like this one:
|
|
1332
1370
|
|
|
@@ -1336,10 +1374,10 @@ const obj = {
|
|
|
1336
1374
|
arr: [1, 2, 3],
|
|
1337
1375
|
arr2: [1, [2], 3],
|
|
1338
1376
|
users: [
|
|
1339
|
-
{ name:
|
|
1340
|
-
{ name:
|
|
1377
|
+
{ name: 'Peter', surname: 'Griffin' },
|
|
1378
|
+
{ name: 'Thomas', surname: 'Anderson' },
|
|
1341
1379
|
],
|
|
1342
|
-
|
|
1380
|
+
'obj2{}': [{ x: 1 }],
|
|
1343
1381
|
};
|
|
1344
1382
|
```
|
|
1345
1383
|
|
|
@@ -1347,18 +1385,18 @@ The following steps will be executed by the Axios serializer internally:
|
|
|
1347
1385
|
|
|
1348
1386
|
```js
|
|
1349
1387
|
const formData = new FormData();
|
|
1350
|
-
formData.append(
|
|
1351
|
-
formData.append(
|
|
1352
|
-
formData.append(
|
|
1353
|
-
formData.append(
|
|
1354
|
-
formData.append(
|
|
1355
|
-
formData.append(
|
|
1356
|
-
formData.append(
|
|
1357
|
-
formData.append(
|
|
1358
|
-
formData.append(
|
|
1359
|
-
formData.append(
|
|
1360
|
-
formData.append(
|
|
1361
|
-
formData.append(
|
|
1388
|
+
formData.append('x', '1');
|
|
1389
|
+
formData.append('arr[]', '1');
|
|
1390
|
+
formData.append('arr[]', '2');
|
|
1391
|
+
formData.append('arr[]', '3');
|
|
1392
|
+
formData.append('arr2[0]', '1');
|
|
1393
|
+
formData.append('arr2[1][0]', '2');
|
|
1394
|
+
formData.append('arr2[2]', '3');
|
|
1395
|
+
formData.append('users[0][name]', 'Peter');
|
|
1396
|
+
formData.append('users[0][surname]', 'Griffin');
|
|
1397
|
+
formData.append('users[1][name]', 'Thomas');
|
|
1398
|
+
formData.append('users[1][surname]', 'Anderson');
|
|
1399
|
+
formData.append('obj2{}', '[{"x":1}]');
|
|
1362
1400
|
```
|
|
1363
1401
|
|
|
1364
1402
|
Axios supports the following shortcut methods: `postForm`, `putForm`, `patchForm`
|
|
@@ -1369,27 +1407,24 @@ which are just the corresponding http methods with the `Content-Type` header pre
|
|
|
1369
1407
|
You can easily submit a single file:
|
|
1370
1408
|
|
|
1371
1409
|
```js
|
|
1372
|
-
await axios.postForm(
|
|
1373
|
-
myVar:
|
|
1374
|
-
file: document.querySelector(
|
|
1410
|
+
await axios.postForm('https://httpbin.org/post', {
|
|
1411
|
+
myVar: 'foo',
|
|
1412
|
+
file: document.querySelector('#fileInput').files[0],
|
|
1375
1413
|
});
|
|
1376
1414
|
```
|
|
1377
1415
|
|
|
1378
1416
|
or multiple files as `multipart/form-data`:
|
|
1379
1417
|
|
|
1380
1418
|
```js
|
|
1381
|
-
await axios.postForm(
|
|
1382
|
-
|
|
1419
|
+
await axios.postForm('https://httpbin.org/post', {
|
|
1420
|
+
'files[]': document.querySelector('#fileInput').files,
|
|
1383
1421
|
});
|
|
1384
1422
|
```
|
|
1385
1423
|
|
|
1386
1424
|
`FileList` object can be passed directly:
|
|
1387
1425
|
|
|
1388
1426
|
```js
|
|
1389
|
-
await axios.postForm(
|
|
1390
|
-
"https://httpbin.org/post",
|
|
1391
|
-
document.querySelector("#fileInput").files,
|
|
1392
|
-
);
|
|
1427
|
+
await axios.postForm('https://httpbin.org/post', document.querySelector('#fileInput').files);
|
|
1393
1428
|
```
|
|
1394
1429
|
|
|
1395
1430
|
All files will be sent with the same field names: `files[]`.
|
|
@@ -1399,24 +1434,17 @@ All files will be sent with the same field names: `files[]`.
|
|
|
1399
1434
|
Pass an HTML Form element as a payload to submit it as `multipart/form-data` content.
|
|
1400
1435
|
|
|
1401
1436
|
```js
|
|
1402
|
-
await axios.postForm(
|
|
1403
|
-
"https://httpbin.org/post",
|
|
1404
|
-
document.querySelector("#htmlForm"),
|
|
1405
|
-
);
|
|
1437
|
+
await axios.postForm('https://httpbin.org/post', document.querySelector('#htmlForm'));
|
|
1406
1438
|
```
|
|
1407
1439
|
|
|
1408
1440
|
`FormData` and `HTMLForm` objects can also be posted as `JSON` by explicitly setting the `Content-Type` header to `application/json`:
|
|
1409
1441
|
|
|
1410
1442
|
```js
|
|
1411
|
-
await axios.post(
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
{
|
|
1415
|
-
headers: {
|
|
1416
|
-
"Content-Type": "application/json",
|
|
1417
|
-
},
|
|
1443
|
+
await axios.post('https://httpbin.org/post', document.querySelector('#htmlForm'), {
|
|
1444
|
+
headers: {
|
|
1445
|
+
'Content-Type': 'application/json',
|
|
1418
1446
|
},
|
|
1419
|
-
);
|
|
1447
|
+
});
|
|
1420
1448
|
```
|
|
1421
1449
|
|
|
1422
1450
|
For example, the Form
|
|
@@ -1503,7 +1531,7 @@ const { data } = await axios.post(SERVER_URL, readableStream, {
|
|
|
1503
1531
|
},
|
|
1504
1532
|
|
|
1505
1533
|
headers: {
|
|
1506
|
-
|
|
1534
|
+
'Content-Length': contentLength,
|
|
1507
1535
|
},
|
|
1508
1536
|
|
|
1509
1537
|
maxRedirects: 0, // avoid buffering the entire stream
|
|
@@ -1524,9 +1552,7 @@ Download and upload rate limits can only be set for the http adapter (node.js):
|
|
|
1524
1552
|
```js
|
|
1525
1553
|
const { data } = await axios.post(LOCAL_SERVER_URL, myBuffer, {
|
|
1526
1554
|
onUploadProgress: ({ progress, rate }) => {
|
|
1527
|
-
console.log(
|
|
1528
|
-
`Upload [${(progress * 100).toFixed(2)}%]: ${(rate / 1024).toFixed(2)}KB/s`,
|
|
1529
|
-
);
|
|
1555
|
+
console.log(`Upload [${(progress * 100).toFixed(2)}%]: ${(rate / 1024).toFixed(2)}KB/s`);
|
|
1530
1556
|
},
|
|
1531
1557
|
|
|
1532
1558
|
maxRate: [100 * 1024], // 100KB/s limit
|
|
@@ -1561,18 +1587,18 @@ The headers object is always initialized inside interceptors and transformers:
|
|
|
1561
1587
|
|
|
1562
1588
|
```ts
|
|
1563
1589
|
axios.interceptors.request.use((request: InternalAxiosRequestConfig) => {
|
|
1564
|
-
request.headers.set(
|
|
1590
|
+
request.headers.set('My-header', 'value');
|
|
1565
1591
|
|
|
1566
1592
|
request.headers.set({
|
|
1567
|
-
|
|
1568
|
-
|
|
1593
|
+
'My-set-header1': 'my-set-value1',
|
|
1594
|
+
'My-set-header2': 'my-set-value2',
|
|
1569
1595
|
});
|
|
1570
1596
|
|
|
1571
|
-
request.headers.set(
|
|
1597
|
+
request.headers.set('User-Agent', false); // disable subsequent setting the header by Axios
|
|
1572
1598
|
|
|
1573
|
-
request.headers.setContentType(
|
|
1599
|
+
request.headers.setContentType('text/plain');
|
|
1574
1600
|
|
|
1575
|
-
request.headers[
|
|
1601
|
+
request.headers['My-set-header2'] = 'newValue'; // direct access is deprecated
|
|
1576
1602
|
|
|
1577
1603
|
return request;
|
|
1578
1604
|
});
|
|
@@ -1582,9 +1608,9 @@ You can iterate over an `AxiosHeaders` instance using a `for...of` statement:
|
|
|
1582
1608
|
|
|
1583
1609
|
```js
|
|
1584
1610
|
const headers = new AxiosHeaders({
|
|
1585
|
-
foo:
|
|
1586
|
-
bar:
|
|
1587
|
-
baz:
|
|
1611
|
+
foo: '1',
|
|
1612
|
+
bar: '2',
|
|
1613
|
+
baz: '3',
|
|
1588
1614
|
});
|
|
1589
1615
|
|
|
1590
1616
|
for (const [header, value] of headers) {
|
|
@@ -1683,26 +1709,26 @@ matcher function or internal key-value parser.
|
|
|
1683
1709
|
|
|
1684
1710
|
```ts
|
|
1685
1711
|
const headers = new AxiosHeaders({
|
|
1686
|
-
|
|
1712
|
+
'Content-Type': 'multipart/form-data; boundary=Asrf456BGe4h',
|
|
1687
1713
|
});
|
|
1688
1714
|
|
|
1689
|
-
console.log(headers.get(
|
|
1715
|
+
console.log(headers.get('Content-Type'));
|
|
1690
1716
|
// multipart/form-data; boundary=Asrf456BGe4h
|
|
1691
1717
|
|
|
1692
|
-
console.log(headers.get(
|
|
1718
|
+
console.log(headers.get('Content-Type', true)); // parse key-value pairs from a string separated with \s,;= delimiters:
|
|
1693
1719
|
// [Object: null prototype] {
|
|
1694
1720
|
// 'multipart/form-data': undefined,
|
|
1695
1721
|
// boundary: 'Asrf456BGe4h'
|
|
1696
1722
|
// }
|
|
1697
1723
|
|
|
1698
1724
|
console.log(
|
|
1699
|
-
headers.get(
|
|
1700
|
-
return String(value).replace(/a/g,
|
|
1701
|
-
})
|
|
1725
|
+
headers.get('Content-Type', (value, name, headers) => {
|
|
1726
|
+
return String(value).replace(/a/g, 'ZZZ');
|
|
1727
|
+
})
|
|
1702
1728
|
);
|
|
1703
1729
|
// multipZZZrt/form-dZZZtZZZ; boundZZZry=Asrf456BGe4h
|
|
1704
1730
|
|
|
1705
|
-
console.log(headers.get(
|
|
1731
|
+
console.log(headers.get('Content-Type', /boundary=(\w+)/)?.[0]);
|
|
1706
1732
|
// boundary=Asrf456BGe4h
|
|
1707
1733
|
```
|
|
1708
1734
|
|
|
@@ -1735,9 +1761,9 @@ Unlike the `delete` method matcher, this optional matcher will be used to match
|
|
|
1735
1761
|
|
|
1736
1762
|
```ts
|
|
1737
1763
|
const headers = new AxiosHeaders({
|
|
1738
|
-
foo:
|
|
1739
|
-
|
|
1740
|
-
|
|
1764
|
+
foo: '1',
|
|
1765
|
+
'x-foo': '2',
|
|
1766
|
+
'x-bar': '3',
|
|
1741
1767
|
});
|
|
1742
1768
|
|
|
1743
1769
|
console.log(headers.clear(/^x-/)); // true
|
|
@@ -1756,11 +1782,11 @@ Set `format` to true for converting header names to lowercase and capitalizing t
|
|
|
1756
1782
|
|
|
1757
1783
|
```js
|
|
1758
1784
|
const headers = new AxiosHeaders({
|
|
1759
|
-
foo:
|
|
1785
|
+
foo: '1',
|
|
1760
1786
|
});
|
|
1761
1787
|
|
|
1762
|
-
headers.Foo =
|
|
1763
|
-
headers.FOO =
|
|
1788
|
+
headers.Foo = '2';
|
|
1789
|
+
headers.FOO = '3';
|
|
1764
1790
|
|
|
1765
1791
|
console.log(headers.toJSON()); // [Object: null prototype] { foo: '1', Foo: '2', FOO: '3' }
|
|
1766
1792
|
console.log(headers.normalize().toJSON()); // [Object: null prototype] { foo: '3' }
|
|
@@ -1827,7 +1853,7 @@ To use it by default, it must be selected explicitly:
|
|
|
1827
1853
|
|
|
1828
1854
|
```js
|
|
1829
1855
|
const { data } = axios.get(url, {
|
|
1830
|
-
adapter:
|
|
1856
|
+
adapter: 'fetch', // by default ['xhr', 'http', 'fetch']
|
|
1831
1857
|
});
|
|
1832
1858
|
```
|
|
1833
1859
|
|
|
@@ -1835,7 +1861,7 @@ You can create a separate instance for this:
|
|
|
1835
1861
|
|
|
1836
1862
|
```js
|
|
1837
1863
|
const fetchAxios = axios.create({
|
|
1838
|
-
adapter:
|
|
1864
|
+
adapter: 'fetch',
|
|
1839
1865
|
});
|
|
1840
1866
|
|
|
1841
1867
|
const { data } = fetchAxios.get(url);
|
|
@@ -1859,12 +1885,12 @@ you must disable their use inside the fetch adapter by passing null.
|
|
|
1859
1885
|
Basic example:
|
|
1860
1886
|
|
|
1861
1887
|
```js
|
|
1862
|
-
import customFetchFunction from
|
|
1888
|
+
import customFetchFunction from 'customFetchModule';
|
|
1863
1889
|
|
|
1864
1890
|
const instance = axios.create({
|
|
1865
|
-
adapter:
|
|
1891
|
+
adapter: 'fetch',
|
|
1866
1892
|
onDownloadProgress(e) {
|
|
1867
|
-
console.log(
|
|
1893
|
+
console.log('downloadProgress', e);
|
|
1868
1894
|
},
|
|
1869
1895
|
env: {
|
|
1870
1896
|
fetch: customFetchFunction,
|
|
@@ -1879,20 +1905,20 @@ const instance = axios.create({
|
|
|
1879
1905
|
A minimal example of setting up Axios for use in a [Tauri](https://tauri.app/plugin/http-client/) app with a platform fetch function that ignores CORS policy for requests.
|
|
1880
1906
|
|
|
1881
1907
|
```js
|
|
1882
|
-
import { fetch } from
|
|
1883
|
-
import axios from
|
|
1908
|
+
import { fetch } from '@tauri-apps/plugin-http';
|
|
1909
|
+
import axios from 'axios';
|
|
1884
1910
|
|
|
1885
1911
|
const instance = axios.create({
|
|
1886
|
-
adapter:
|
|
1912
|
+
adapter: 'fetch',
|
|
1887
1913
|
onDownloadProgress(e) {
|
|
1888
|
-
console.log(
|
|
1914
|
+
console.log('downloadProgress', e);
|
|
1889
1915
|
},
|
|
1890
1916
|
env: {
|
|
1891
1917
|
fetch,
|
|
1892
1918
|
},
|
|
1893
1919
|
});
|
|
1894
1920
|
|
|
1895
|
-
const { data } = await instance.get(
|
|
1921
|
+
const { data } = await instance.get('https://google.com');
|
|
1896
1922
|
```
|
|
1897
1923
|
|
|
1898
1924
|
#### 🔥 Using with SvelteKit
|
|
@@ -1902,17 +1928,14 @@ which makes it incompatible with the standard URL API. So, Axios must be configu
|
|
|
1902
1928
|
|
|
1903
1929
|
```js
|
|
1904
1930
|
export async function load({ fetch }) {
|
|
1905
|
-
const { data: post } = await axios.get(
|
|
1906
|
-
|
|
1907
|
-
{
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
Request: null,
|
|
1912
|
-
Response: null,
|
|
1913
|
-
},
|
|
1931
|
+
const { data: post } = await axios.get('https://jsonplaceholder.typicode.com/posts/1', {
|
|
1932
|
+
adapter: 'fetch',
|
|
1933
|
+
env: {
|
|
1934
|
+
fetch,
|
|
1935
|
+
Request: null,
|
|
1936
|
+
Response: null,
|
|
1914
1937
|
},
|
|
1915
|
-
);
|
|
1938
|
+
});
|
|
1916
1939
|
|
|
1917
1940
|
return { post };
|
|
1918
1941
|
}
|
|
@@ -1931,21 +1954,17 @@ Note: HTTP/2 redirects are currently not supported by the HTTP/2 adapter.
|
|
|
1931
1954
|
```js
|
|
1932
1955
|
const form = new FormData();
|
|
1933
1956
|
|
|
1934
|
-
form.append(
|
|
1957
|
+
form.append('foo', '123');
|
|
1935
1958
|
|
|
1936
|
-
const { data, headers, status } = await axios.post(
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
},
|
|
1946
|
-
responseType: "arraybuffer",
|
|
1947
|
-
}
|
|
1948
|
-
);
|
|
1959
|
+
const { data, headers, status } = await axios.post('https://httpbin.org/post', form, {
|
|
1960
|
+
onUploadProgress(e) {
|
|
1961
|
+
console.log('upload progress', e);
|
|
1962
|
+
},
|
|
1963
|
+
onDownloadProgress(e) {
|
|
1964
|
+
console.log('download progress', e);
|
|
1965
|
+
},
|
|
1966
|
+
responseType: 'arraybuffer',
|
|
1967
|
+
});
|
|
1949
1968
|
```
|
|
1950
1969
|
|
|
1951
1970
|
## Semver
|
|
@@ -1964,7 +1983,7 @@ axios includes [TypeScript](https://typescriptlang.org) definitions and a type g
|
|
|
1964
1983
|
```typescript
|
|
1965
1984
|
let user: User = null;
|
|
1966
1985
|
try {
|
|
1967
|
-
const { data } = await axios.get(
|
|
1986
|
+
const { data } = await axios.get('/user?ID=12345');
|
|
1968
1987
|
user = data.userDetails;
|
|
1969
1988
|
} catch (error) {
|
|
1970
1989
|
if (axios.isAxiosError(error)) {
|
|
@@ -1984,10 +2003,10 @@ If you use TypeScript to type check CJS JavaScript code, your only option is to
|
|
|
1984
2003
|
You can also create a custom instance with typed interceptors:
|
|
1985
2004
|
|
|
1986
2005
|
```typescript
|
|
1987
|
-
import axios, { AxiosInstance, InternalAxiosRequestConfig } from
|
|
2006
|
+
import axios, { AxiosInstance, InternalAxiosRequestConfig } from 'axios';
|
|
1988
2007
|
|
|
1989
2008
|
const apiClient: AxiosInstance = axios.create({
|
|
1990
|
-
baseURL:
|
|
2009
|
+
baseURL: 'https://api.example.com',
|
|
1991
2010
|
timeout: 10000,
|
|
1992
2011
|
});
|
|
1993
2012
|
|
|
@@ -2003,6 +2022,23 @@ You can use Gitpod, an online IDE(which is free for Open Source) for contributin
|
|
|
2003
2022
|
|
|
2004
2023
|
[](https://gitpod.io/#https://github.com/axios/axios/blob/main/examples/server.js)
|
|
2005
2024
|
|
|
2025
|
+
## Contributing
|
|
2026
|
+
|
|
2027
|
+
### Local setup
|
|
2028
|
+
|
|
2029
|
+
As a supply-chain hardening measure, this repository ships a project-level `.npmrc` that sets `ignore-scripts=true`. This blocks npm lifecycle scripts (`preinstall`, `install`, `postinstall`, `prepare`) from any direct or transitive dependency when you run `npm install` or `npm ci` inside the repo. See [THREATMODEL.md](./THREATMODEL.md) (threat T-S2) for the rationale.
|
|
2030
|
+
|
|
2031
|
+
One consequence: the repository's own `prepare` hook (which installs Husky's git hooks) will **not** run automatically. After your first install, enable the git hooks manually:
|
|
2032
|
+
|
|
2033
|
+
```bash
|
|
2034
|
+
npm ci
|
|
2035
|
+
npm rebuild husky && npx husky
|
|
2036
|
+
```
|
|
2037
|
+
|
|
2038
|
+
Run those two commands once per fresh checkout. You do **not** need to re-run them after every subsequent `npm install`.
|
|
2039
|
+
|
|
2040
|
+
Do not remove `ignore-scripts=true` from `.npmrc` to "fix" this — that re-opens the lifecycle-script attack surface for every other package in the tree. All CI workflows already invoke npm with `--ignore-scripts`, so local behaviour matches CI.
|
|
2041
|
+
|
|
2006
2042
|
## Resources
|
|
2007
2043
|
|
|
2008
2044
|
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
|