UNPKG

42.3 kBMarkdownView Raw
1<h1 align="center">
2 <b>
3 <a href="https://axios-http.com"><img src="https://axios-http.com/assets/logo.svg" /></a><br>
4 </b>
5</h1>
6
7<p align="center">Promise based HTTP client for the browser and node.js</p>
8
9<p align="center">
10 <a href="https://axios-http.com/"><b>Website</b></a> •
11 <a href="https://axios-http.com/docs/intro"><b>Documentation</b></a>
12</p>
13
14<div align="center">
15
16[![npm version](https://img.shields.io/npm/v/axios.svg?style=flat-square)](https://www.npmjs.org/package/axios)
17[![CDNJS](https://img.shields.io/cdnjs/v/axios.svg?style=flat-square)](https://cdnjs.com/libraries/axios)
18[![Build status](https://img.shields.io/github/workflow/status/axios/axios/ci?label=CI&logo=github&style=flat-square)](https://github.com/axios/axios/actions/workflows/ci.yml)
19[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square)](https://gitpod.io/#https://github.com/axios/axios)
20[![code coverage](https://img.shields.io/coveralls/mzabriskie/axios.svg?style=flat-square)](https://coveralls.io/r/mzabriskie/axios)
21[![install size](https://img.shields.io/badge/dynamic/json?url=https://packagephobia.com/v2/api.json?p=axios&query=$.install.pretty&label=install%20size&style=flat-square)](https://packagephobia.now.sh/result?p=axios)
22[![npm bundle size](https://img.shields.io/bundlephobia/minzip/axios?style=flat-square)](https://bundlephobia.com/package/axios@latest)
23[![npm downloads](https://img.shields.io/npm/dm/axios.svg?style=flat-square)](https://npm-stat.com/charts.html?package=axios)
24[![gitter chat](https://img.shields.io/gitter/room/mzabriskie/axios.svg?style=flat-square)](https://gitter.im/mzabriskie/axios)
25[![code helpers](https://www.codetriage.com/axios/axios/badges/users.svg)](https://www.codetriage.com/axios/axios)
26[![Known Vulnerabilities](https://snyk.io/test/npm/axios/badge.svg)](https://snyk.io/test/npm/axios)
27
28
29
30
31</div>
32
33## Table of Contents
34
35 - [Features](#features)
36 - [Browser Support](#browser-support)
37 - [Installing](#installing)
38 - [Example](#example)
39 - [Axios API](#axios-api)
40 - [Request method aliases](#request-method-aliases)
41 - [Concurrency 👎](#concurrency-deprecated)
42 - [Creating an instance](#creating-an-instance)
43 - [Instance methods](#instance-methods)
44 - [Request Config](#request-config)
45 - [Response Schema](#response-schema)
46 - [Config Defaults](#config-defaults)
47 - [Global axios defaults](#global-axios-defaults)
48 - [Custom instance defaults](#custom-instance-defaults)
49 - [Config order of precedence](#config-order-of-precedence)
50 - [Interceptors](#interceptors)
51 - [Multiple Interceptors](#multiple-interceptors)
52 - [Handling Errors](#handling-errors)
53 - [Cancellation](#cancellation)
54 - [AbortController](#abortcontroller)
55 - [CancelToken 👎](#canceltoken-deprecated)
56 - [Using application/x-www-form-urlencoded format](#using-applicationx-www-form-urlencoded-format)
57 - [URLSearchParams](#urlsearchparams)
58 - [Query string](#query-string-older-browsers)
59 - [🆕 Automatic serialization](#-automatic-serialization-to-urlsearchparams)
60 - [Using multipart/form-data format](#using-multipartform-data-format)
61 - [FormData](#formdata)
62 - [🆕 Automatic serialization](#-automatic-serialization-to-formdata)
63 - [Files Posting](#files-posting)
64 - [HTML Form Posting](#-html-form-posting-browser)
65 - [🆕 Progress capturing](#-progress-capturing)
66 - [🆕 Rate limiting](#-progress-capturing)
67 - [Semver](#semver)
68 - [Promises](#promises)
69 - [TypeScript](#typescript)
70 - [Resources](#resources)
71 - [Credits](#credits)
72 - [License](#license)
73
74## Features
75
76- Make [XMLHttpRequests](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) from the browser
77- Make [http](https://nodejs.org/api/http.html) requests from node.js
78- Supports the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) API
79- Intercept request and response
80- Transform request and response data
81- Cancel requests
82- Automatic transforms for JSON data
83- 🆕 Automatic data object serialization to `multipart/form-data` and `x-www-form-urlencoded` body encodings
84- Client side support for protecting against [XSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
85
86## Browser Support
87
88![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox_48x48.png) | ![Safari](https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari/safari_48x48.png) | ![Opera](https://raw.githubusercontent.com/alrra/browser-logos/main/src/opera/opera_48x48.png) | ![Edge](https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge_48x48.png) | ![IE](https://raw.githubusercontent.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png) |
89--- | --- | --- | --- | --- | --- |
90Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | 11 ✔ |
91
92[![Browser Matrix](https://saucelabs.com/open_sauce/build_matrix/axios.svg)](https://saucelabs.com/u/axios)
93
94## Installing
95
96Using npm:
97
98```bash
99$ npm install axios
100```
101
102Using bower:
103
104```bash
105$ bower install axios
106```
107
108Using yarn:
109
110```bash
111$ yarn add axios
112```
113
114Using pnpm:
115
116```bash
117$ pnpm add axios
118```
119
120Using jsDelivr CDN:
121
122```html
123<script src="https://cdn.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>
124```
125
126Using unpkg CDN:
127
128```html
129<script src="https://unpkg.com/axios@1.1.2/dist/axios.min.js"></script>
130```
131
132## Example
133
134### note: CommonJS usage
135In order to gain the TypeScript typings (for intellisense / autocomplete) while using CommonJS imports with `require()` use the following approach:
136
137```js
138const axios = require('axios').default;
139
140// axios.<method> will now provide autocomplete and parameter typings
141```
142
143Performing a `GET` request
144
145```js
146const axios = require('axios').default;
147
148// Make a request for a user with a given ID
149axios.get('/user?ID=12345')
150 .then(function (response) {
151 // handle success
152 console.log(response);
153 })
154 .catch(function (error) {
155 // handle error
156 console.log(error);
157 })
158 .finally(function () {
159 // always executed
160 });
161
162// Optionally the request above could also be done as
163axios.get('/user', {
164 params: {
165 ID: 12345
166 }
167 })
168 .then(function (response) {
169 console.log(response);
170 })
171 .catch(function (error) {
172 console.log(error);
173 })
174 .finally(function () {
175 // always executed
176 });
177
178// Want to use async/await? Add the `async` keyword to your outer function/method.
179async function getUser() {
180 try {
181 const response = await axios.get('/user?ID=12345');
182 console.log(response);
183 } catch (error) {
184 console.error(error);
185 }
186}
187```
188
189> **Note** `async/await` is part of ECMAScript 2017 and is not supported in Internet
190> Explorer and older browsers, so use with caution.
191
192Performing a `POST` request
193
194```js
195axios.post('/user', {
196 firstName: 'Fred',
197 lastName: 'Flintstone'
198 })
199 .then(function (response) {
200 console.log(response);
201 })
202 .catch(function (error) {
203 console.log(error);
204 });
205```
206
207Performing multiple concurrent requests
208
209```js
210function getUserAccount() {
211 return axios.get('/user/12345');
212}
213
214function getUserPermissions() {
215 return axios.get('/user/12345/permissions');
216}
217
218Promise.all([getUserAccount(), getUserPermissions()])
219 .then(function (results) {
220 const acct = results[0];
221 const perm = results[1];
222 });
223```
224
225## axios API
226
227Requests can be made by passing the relevant config to `axios`.
228
229##### axios(config)
230
231```js
232// Send a POST request
233axios({
234 method: 'post',
235 url: '/user/12345',
236 data: {
237 firstName: 'Fred',
238 lastName: 'Flintstone'
239 }
240});
241```
242
243```js
244// GET request for remote image in node.js
245axios({
246 method: 'get',
247 url: 'https://bit.ly/2mTM3nY',
248 responseType: 'stream'
249})
250 .then(function (response) {
251 response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
252 });
253```
254
255##### axios(url[, config])
256
257```js
258// Send a GET request (default method)
259axios('/user/12345');
260```
261
262### Request method aliases
263
264For convenience, aliases have been provided for all common request methods.
265
266##### axios.request(config)
267##### axios.get(url[, config])
268##### axios.delete(url[, config])
269##### axios.head(url[, config])
270##### axios.options(url[, config])
271##### axios.post(url[, data[, config]])
272##### axios.put(url[, data[, config]])
273##### axios.patch(url[, data[, config]])
274
275###### NOTE
276When using the alias methods `url`, `method`, and `data` properties don't need to be specified in config.
277
278### Concurrency (Deprecated)
279Please use `Promise.all` to replace the below functions.
280
281Helper functions for dealing with concurrent requests.
282
283axios.all(iterable)
284axios.spread(callback)
285
286### Creating an instance
287
288You can create a new instance of axios with a custom config.
289
290##### axios.create([config])
291
292```js
293const instance = axios.create({
294 baseURL: 'https://some-domain.com/api/',
295 timeout: 1000,
296 headers: {'X-Custom-Header': 'foobar'}
297});
298```
299
300### Instance methods
301
302The available instance methods are listed below. The specified config will be merged with the instance config.
303
304##### axios#request(config)
305##### axios#get(url[, config])
306##### axios#delete(url[, config])
307##### axios#head(url[, config])
308##### axios#options(url[, config])
309##### axios#post(url[, data[, config]])
310##### axios#put(url[, data[, config]])
311##### axios#patch(url[, data[, config]])
312##### axios#getUri([config])
313
314## Request Config
315
316These are the available config options for making requests. Only the `url` is required. Requests will default to `GET` if `method` is not specified.
317
318```js
319{
320 // `url` is the server URL that will be used for the request
321 url: '/user',
322
323 // `method` is the request method to be used when making the request
324 method: 'get', // default
325
326 // `baseURL` will be prepended to `url` unless `url` is absolute.
327 // It can be convenient to set `baseURL` for an instance of axios to pass relative URLs
328 // to methods of that instance.
329 baseURL: 'https://some-domain.com/api/',
330
331 // `transformRequest` allows changes to the request data before it is sent to the server
332 // This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'
333 // The last function in the array must return a string or an instance of Buffer, ArrayBuffer,
334 // FormData or Stream
335 // You may modify the headers object.
336 transformRequest: [function (data, headers) {
337 // Do whatever you want to transform the data
338
339 return data;
340 }],
341
342 // `transformResponse` allows changes to the response data to be made before
343 // it is passed to then/catch
344 transformResponse: [function (data) {
345 // Do whatever you want to transform the data
346
347 return data;
348 }],
349
350 // `headers` are custom headers to be sent
351 headers: {'X-Requested-With': 'XMLHttpRequest'},
352
353 // `params` are the URL parameters to be sent with the request
354 // Must be a plain object or a URLSearchParams object
355 params: {
356 ID: 12345
357 },
358
359 // `paramsSerializer` is an optional config in charge of serializing `params`
360 paramsSerializer: {
361 encode?: (param: string): string => { /* Do custom ops here and return transformed string */ }, // custom encoder function; sends Key/Values in an iterative fashion
362 serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ), // mimic pre 1.x behavior and send entire params object to a custom serializer func. Allows consumer to control how params are serialized.
363 indexes: false // array indexes format (null - no brackets, false (default) - empty brackets, true - brackets with indexes)
364 },
365
366 // `data` is the data to be sent as the request body
367 // Only applicable for request methods 'PUT', 'POST', 'DELETE , and 'PATCH'
368 // When no `transformRequest` is set, must be of one of the following types:
369 // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
370 // - Browser only: FormData, File, Blob
371 // - Node only: Stream, Buffer, FormData (form-data package)
372 data: {
373 firstName: 'Fred'
374 },
375
376 // syntax alternative to send data into the body
377 // method post
378 // only the value is sent, not the key
379 data: 'Country=Brasil&City=Belo Horizonte',
380
381 // `timeout` specifies the number of milliseconds before the request times out.
382 // If the request takes longer than `timeout`, the request will be aborted.
383 timeout: 1000, // default is `0` (no timeout)
384
385 // `withCredentials` indicates whether or not cross-site Access-Control requests
386 // should be made using credentials
387 withCredentials: false, // default
388
389 // `adapter` allows custom handling of requests which makes testing easier.
390 // Return a promise and supply a valid response (see lib/adapters/README.md).
391 adapter: function (config) {
392 /* ... */
393 },
394
395 // `auth` indicates that HTTP Basic auth should be used, and supplies credentials.
396 // This will set an `Authorization` header, overwriting any existing
397 // `Authorization` custom headers you have set using `headers`.
398 // Please note that only HTTP Basic auth is configurable through this parameter.
399 // For Bearer tokens and such, use `Authorization` custom headers instead.
400 auth: {
401 username: 'janedoe',
402 password: 's00pers3cret'
403 },
404
405 // `responseType` indicates the type of data that the server will respond with
406 // options are: 'arraybuffer', 'document', 'json', 'text', 'stream'
407 // browser only: 'blob'
408 responseType: 'json', // default
409
410 // `responseEncoding` indicates encoding to use for decoding responses (Node.js only)
411 // Note: Ignored for `responseType` of 'stream' or client-side requests
412 responseEncoding: 'utf8', // default
413
414 // `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
415 xsrfCookieName: 'XSRF-TOKEN', // default
416
417 // `xsrfHeaderName` is the name of the http header that carries the xsrf token value
418 xsrfHeaderName: 'X-XSRF-TOKEN', // default
419
420 // `onUploadProgress` allows handling of progress events for uploads
421 // browser & node.js
422 onUploadProgress: function ({loaded, total, progress, bytes, estimated, rate, upload = true}) {
423 // Do whatever you want with the Axios progress event
424 },
425
426 // `onDownloadProgress` allows handling of progress events for downloads
427 // browser & node.js
428 onDownloadProgress: function ({loaded, total, progress, bytes, estimated, rate, download = true}) {
429 // Do whatever you want with the Axios progress event
430 },
431
432 // `maxContentLength` defines the max size of the http response content in bytes allowed in node.js
433 maxContentLength: 2000,
434
435 // `maxBodyLength` (Node only option) defines the max size of the http request content in bytes allowed
436 maxBodyLength: 2000,
437
438 // `validateStatus` defines whether to resolve or reject the promise for a given
439 // HTTP response status code. If `validateStatus` returns `true` (or is set to `null`
440 // or `undefined`), the promise will be resolved; otherwise, the promise will be
441 // rejected.
442 validateStatus: function (status) {
443 return status >= 200 && status < 300; // default
444 },
445
446 // `maxRedirects` defines the maximum number of redirects to follow in node.js.
447 // If set to 0, no redirects will be followed.
448 maxRedirects: 21, // default
449
450 // `beforeRedirect` defines a function that will be called before redirect.
451 // Use this to adjust the request options upon redirecting,
452 // to inspect the latest response headers,
453 // or to cancel the request by throwing an error
454 // If maxRedirects is set to 0, `beforeRedirect` is not used.
455 beforeRedirect: (options, { headers }) => {
456 if (options.hostname === "example.com") {
457 options.auth = "user:password";
458 }
459 },
460
461 // `socketPath` defines a UNIX Socket to be used in node.js.
462 // e.g. '/var/run/docker.sock' to send requests to the docker daemon.
463 // Only either `socketPath` or `proxy` can be specified.
464 // If both are specified, `socketPath` is used.
465 socketPath: null, // default
466
467 // `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
468 // and https requests, respectively, in node.js. This allows options to be added like
469 // `keepAlive` that are not enabled by default.
470 httpAgent: new http.Agent({ keepAlive: true }),
471 httpsAgent: new https.Agent({ keepAlive: true }),
472
473 // `proxy` defines the hostname, port, and protocol of the proxy server.
474 // You can also define your proxy using the conventional `http_proxy` and
475 // `https_proxy` environment variables. If you are using environment variables
476 // for your proxy configuration, you can also define a `no_proxy` environment
477 // variable as a comma-separated list of domains that should not be proxied.
478 // Use `false` to disable proxies, ignoring environment variables.
479 // `auth` indicates that HTTP Basic auth should be used to connect to the proxy, and
480 // supplies credentials.
481 // This will set an `Proxy-Authorization` header, overwriting any existing
482 // `Proxy-Authorization` custom headers you have set using `headers`.
483 // If the proxy server uses HTTPS, then you must set the protocol to `https`.
484 proxy: {
485 protocol: 'https',
486 host: '127.0.0.1',
487 // hostname: '127.0.0.1' // Takes precedence over 'host' if both are defined
488 port: 9000,
489 auth: {
490 username: 'mikeymike',
491 password: 'rapunz3l'
492 }
493 },
494
495 // `cancelToken` specifies a cancel token that can be used to cancel the request
496 // (see Cancellation section below for details)
497 cancelToken: new CancelToken(function (cancel) {
498 }),
499
500 // an alternative way to cancel Axios requests using AbortController
501 signal: new AbortController().signal,
502
503 // `decompress` indicates whether or not the response body should be decompressed
504 // automatically. If set to `true` will also remove the 'content-encoding' header
505 // from the responses objects of all decompressed responses
506 // - Node only (XHR cannot turn off decompression)
507 decompress: true // default
508
509 // `insecureHTTPParser` boolean.
510 // Indicates where to use an insecure HTTP parser that accepts invalid HTTP headers.
511 // This may allow interoperability with non-conformant HTTP implementations.
512 // Using the insecure parser should be avoided.
513 // see options https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback
514 // see also https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing-none
515 insecureHTTPParser: undefined // default
516
517 // transitional options for backward compatibility that may be removed in the newer versions
518 transitional: {
519 // silent JSON parsing mode
520 // `true` - ignore JSON parsing errors and set response.data to null if parsing failed (old behaviour)
521 // `false` - throw SyntaxError if JSON parsing failed (Note: responseType must be set to 'json')
522 silentJSONParsing: true, // default value for the current Axios version
523
524 // try to parse the response string as JSON even if `responseType` is not 'json'
525 forcedJSONParsing: true,
526
527 // throw ETIMEDOUT error instead of generic ECONNABORTED on request timeouts
528 clarifyTimeoutError: false,
529 },
530
531 env: {
532 // The FormData class to be used to automatically serialize the payload into a FormData object
533 FormData: window?.FormData || global?.FormData
534 },
535
536 formSerializer: {
537 visitor: (value, key, path, helpers) => {}; // custom visitor function to serialize form values
538 dots: boolean; // use dots instead of brackets format
539 metaTokens: boolean; // keep special endings like {} in parameter key
540 indexes: boolean; // array indexes format null - no brackets, false - empty brackets, true - brackets with indexes
541 },
542
543 // http adapter only (node.js)
544 maxRate: [
545 100 * 1024, // 100KB/s upload limit,
546 100 * 1024 // 100KB/s download limit
547 ]
548}
549```
550
551## Response Schema
552
553The response for a request contains the following information.
554
555```js
556{
557 // `data` is the response that was provided by the server
558 data: {},
559
560 // `status` is the HTTP status code from the server response
561 status: 200,
562
563 // `statusText` is the HTTP status message from the server response
564 statusText: 'OK',
565
566 // `headers` the HTTP headers that the server responded with
567 // All header names are lowercase and can be accessed using the bracket notation.
568 // Example: `response.headers['content-type']`
569 headers: {},
570
571 // `config` is the config that was provided to `axios` for the request
572 config: {},
573
574 // `request` is the request that generated this response
575 // It is the last ClientRequest instance in node.js (in redirects)
576 // and an XMLHttpRequest instance in the browser
577 request: {}
578}
579```
580
581When using `then`, you will receive the response as follows:
582
583```js
584axios.get('/user/12345')
585 .then(function (response) {
586 console.log(response.data);
587 console.log(response.status);
588 console.log(response.statusText);
589 console.log(response.headers);
590 console.log(response.config);
591 });
592```
593
594When using `catch`, or passing a [rejection callback](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then) as second parameter of `then`, the response will be available through the `error` object as explained in the [Handling Errors](#handling-errors) section.
595
596## Config Defaults
597
598You can specify config defaults that will be applied to every request.
599
600### Global axios defaults
601
602```js
603axios.defaults.baseURL = 'https://api.example.com';
604
605// Important: If axios is used with multiple domains, the AUTH_TOKEN will be sent to all of them.
606// See below for an example using Custom instance defaults instead.
607axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
608
609axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
610```
611
612### Custom instance defaults
613
614```js
615// Set config defaults when creating the instance
616const instance = axios.create({
617 baseURL: 'https://api.example.com'
618});
619
620// Alter defaults after instance has been created
621instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
622```
623
624### Config order of precedence
625
626Config will be merged with an order of precedence. The order is library defaults found in [lib/defaults.js](https://github.com/axios/axios/blob/master/lib/defaults/index.js#L28), then `defaults` property of the instance, and finally `config` argument for the request. The latter will take precedence over the former. Here's an example.
627
628```js
629// Create an instance using the config defaults provided by the library
630// At this point the timeout config value is `0` as is the default for the library
631const instance = axios.create();
632
633// Override timeout default for the library
634// Now all requests using this instance will wait 2.5 seconds before timing out
635instance.defaults.timeout = 2500;
636
637// Override timeout for this request as it's known to take a long time
638instance.get('/longRequest', {
639 timeout: 5000
640});
641```
642
643## Interceptors
644
645You can intercept requests or responses before they are handled by `then` or `catch`.
646
647```js
648// Add a request interceptor
649axios.interceptors.request.use(function (config) {
650 // Do something before request is sent
651 return config;
652 }, function (error) {
653 // Do something with request error
654 return Promise.reject(error);
655 });
656
657// Add a response interceptor
658axios.interceptors.response.use(function (response) {
659 // Any status code that lie within the range of 2xx cause this function to trigger
660 // Do something with response data
661 return response;
662 }, function (error) {
663 // Any status codes that falls outside the range of 2xx cause this function to trigger
664 // Do something with response error
665 return Promise.reject(error);
666 });
667```
668
669If you need to remove an interceptor later you can.
670
671```js
672const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
673axios.interceptors.request.eject(myInterceptor);
674```
675
676You can also clear all interceptors for requests or responses.
677```js
678const instance = axios.create();
679instance.interceptors.request.use(function () {/*...*/});
680instance.interceptors.request.clear(); // Removes interceptors from requests
681instance.interceptors.response.use(function () {/*...*/});
682instance.interceptors.response.clear(); // Removes interceptors from responses
683```
684
685You can add interceptors to a custom instance of axios.
686
687```js
688const instance = axios.create();
689instance.interceptors.request.use(function () {/*...*/});
690```
691
692When you add request interceptors, they are presumed to be asynchronous by default. This can cause a delay
693in the execution of your axios request when the main thread is blocked (a promise is created under the hood for
694the interceptor and your request gets put on the bottom of the call stack). If your request interceptors are synchronous you can add a flag
695to the options object that will tell axios to run the code synchronously and avoid any delays in request execution.
696
697```js
698axios.interceptors.request.use(function (config) {
699 config.headers.test = 'I am only a header!';
700 return config;
701}, null, { synchronous: true });
702```
703
704If you want to execute a particular interceptor based on a runtime check,
705you can add a `runWhen` function to the options object. The interceptor will not be executed **if and only if** the return
706of `runWhen` is `false`. The function will be called with the config
707object (don't forget that you can bind your own arguments to it as well.) This can be handy when you have an
708asynchronous request interceptor that only needs to run at certain times.
709
710```js
711function onGetCall(config) {
712 return config.method === 'get';
713}
714axios.interceptors.request.use(function (config) {
715 config.headers.test = 'special get headers';
716 return config;
717}, null, { runWhen: onGetCall });
718```
719
720### Multiple Interceptors
721
722Given you add multiple response interceptors
723and when the response was fulfilled
724- then each interceptor is executed
725- then they are executed in the order they were added
726- then only the last interceptor's result is returned
727- then every interceptor receives the result of its predecessor
728- and when the fulfillment-interceptor throws
729 - then the following fulfillment-interceptor is not called
730 - then the following rejection-interceptor is called
731 - once caught, another following fulfill-interceptor is called again (just like in a promise chain).
732
733Read [the interceptor tests](./test/specs/interceptors.spec.js) for seeing all this in code.
734
735## Handling Errors
736
737```js
738axios.get('/user/12345')
739 .catch(function (error) {
740 if (error.response) {
741 // The request was made and the server responded with a status code
742 // that falls out of the range of 2xx
743 console.log(error.response.data);
744 console.log(error.response.status);
745 console.log(error.response.headers);
746 } else if (error.request) {
747 // The request was made but no response was received
748 // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
749 // http.ClientRequest in node.js
750 console.log(error.request);
751 } else {
752 // Something happened in setting up the request that triggered an Error
753 console.log('Error', error.message);
754 }
755 console.log(error.config);
756 });
757```
758
759Using the `validateStatus` config option, you can define HTTP code(s) that should throw an error.
760
761```js
762axios.get('/user/12345', {
763 validateStatus: function (status) {
764 return status < 500; // Resolve only if the status code is less than 500
765 }
766})
767```
768
769Using `toJSON` you get an object with more information about the HTTP error.
770
771```js
772axios.get('/user/12345')
773 .catch(function (error) {
774 console.log(error.toJSON());
775 });
776```
777
778## Cancellation
779
780### AbortController
781
782Starting from `v0.22.0` Axios supports AbortController to cancel requests in fetch API way:
783
784```js
785const controller = new AbortController();
786
787axios.get('/foo/bar', {
788 signal: controller.signal
789}).then(function(response) {
790 //...
791});
792// cancel the request
793controller.abort()
794```
795
796### CancelToken `👎deprecated`
797
798You can also cancel a request using a *CancelToken*.
799
800> The axios cancel token API is based on the withdrawn [cancelable promises proposal](https://github.com/tc39/proposal-cancelable-promises).
801
802> This API is deprecated since v0.22.0 and shouldn't be used in new projects
803
804You can create a cancel token using the `CancelToken.source` factory as shown below:
805
806```js
807const CancelToken = axios.CancelToken;
808const source = CancelToken.source();
809
810axios.get('/user/12345', {
811 cancelToken: source.token
812}).catch(function (thrown) {
813 if (axios.isCancel(thrown)) {
814 console.log('Request canceled', thrown.message);
815 } else {
816 // handle error
817 }
818});
819
820axios.post('/user/12345', {
821 name: 'new name'
822}, {
823 cancelToken: source.token
824})
825
826// cancel the request (the message parameter is optional)
827source.cancel('Operation canceled by the user.');
828```
829
830You can also create a cancel token by passing an executor function to the `CancelToken` constructor:
831
832```js
833const CancelToken = axios.CancelToken;
834let cancel;
835
836axios.get('/user/12345', {
837 cancelToken: new CancelToken(function executor(c) {
838 // An executor function receives a cancel function as a parameter
839 cancel = c;
840 })
841});
842
843// cancel the request
844cancel();
845```
846
847> **Note:** you can cancel several requests with the same cancel token/abort controller.
848> If a cancellation token is already cancelled at the moment of starting an Axios request, then the request is cancelled immediately, without any attempts to make a real request.
849
850> During the transition period, you can use both cancellation APIs, even for the same request:
851
852## Using `application/x-www-form-urlencoded` format
853
854### URLSearchParams
855
856By default, axios serializes JavaScript objects to `JSON`. To send data in the [`application/x-www-form-urlencoded` format](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) 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).
857
858```js
859const params = new URLSearchParams({ foo: 'bar' });
860params.append('extraparam', 'value');
861axios.post('/foo', params);
862```
863
864### Query string (Older browsers)
865
866For compatibility with very old browsers, there is a [polyfill](https://github.com/WebReflection/url-search-params) available (make sure to polyfill the global environment).
867
868Alternatively, you can encode data using the [`qs`](https://github.com/ljharb/qs) library:
869
870```js
871const qs = require('qs');
872axios.post('/foo', qs.stringify({ 'bar': 123 }));
873```
874
875Or in another way (ES6),
876
877```js
878import qs from 'qs';
879const data = { 'bar': 123 };
880const options = {
881 method: 'POST',
882 headers: { 'content-type': 'application/x-www-form-urlencoded' },
883 data: qs.stringify(data),
884 url,
885};
886axios(options);
887```
888
889### Older Node.js versions
890
891For older Node.js engines, you can use the [`querystring`](https://nodejs.org/api/querystring.html) module as follows:
892
893```js
894const querystring = require('querystring');
895axios.post('https://something.com/', querystring.stringify({ foo: 'bar' }));
896```
897
898You can also use the [`qs`](https://github.com/ljharb/qs) library.
899
900> **Note**
901> The `qs` library is preferable if you need to stringify nested objects, as the `querystring` method has [known issues](https://github.com/nodejs/node-v0.x-archive/issues/1665) with that use case.
902
903### 🆕 Automatic serialization to URLSearchParams
904
905Axios will automatically serialize the data object to urlencoded format if the content-type header is set to "application/x-www-form-urlencoded".
906
907```js
908const data = {
909 x: 1,
910 arr: [1, 2, 3],
911 arr2: [1, [2], 3],
912 users: [{name: 'Peter', surname: 'Griffin'}, {name: 'Thomas', surname: 'Anderson'}],
913};
914
915await axios.postForm('https://postman-echo.com/post', data,
916 {headers: {'content-type': 'application/x-www-form-urlencoded'}}
917);
918```
919
920The server will handle it as
921
922```js
923 {
924 x: '1',
925 'arr[]': [ '1', '2', '3' ],
926 'arr2[0]': '1',
927 'arr2[1][0]': '2',
928 'arr2[2]': '3',
929 'arr3[]': [ '1', '2', '3' ],
930 'users[0][name]': 'Peter',
931 'users[0][surname]': 'griffin',
932 'users[1][name]': 'Thomas',
933 'users[1][surname]': 'Anderson'
934 }
935````
936
937If your backend body-parser (like `body-parser` of `express.js`) supports nested objects decoding, you will get the same object on the server-side automatically
938
939```js
940 var app = express();
941
942 app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
943
944 app.post('/', function (req, res, next) {
945 // echo body as JSON
946 res.send(JSON.stringify(req.body));
947 });
948
949 server = app.listen(3000);
950```
951
952## Using `multipart/form-data` format
953
954### FormData
955
956To send the data as a `multipart/formdata` you need to pass a formData instance as a payload.
957Setting the `Content-Type` header is not required as Axios guesses it based on the payload type.
958
959```js
960const formData = new FormData();
961formData.append('foo', 'bar');
962
963axios.post('https://httpbin.org/post', formData);
964```
965
966In node.js, you can use the [`form-data`](https://github.com/form-data/form-data) library as follows:
967
968```js
969const FormData = require('form-data');
970
971const form = new FormData();
972form.append('my_field', 'my value');
973form.append('my_buffer', new Buffer(10));
974form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
975
976axios.post('https://example.com', form)
977```
978
979### 🆕 Automatic serialization to FormData
980
981Starting from `v0.27.0`, Axios supports automatic object serialization to a FormData object if the request `Content-Type`
982header is set to `multipart/form-data`.
983
984The following request will submit the data in a FormData format (Browser & Node.js):
985
986```js
987import axios from 'axios';
988
989axios.post('https://httpbin.org/post', {x: 1}, {
990 headers: {
991 'Content-Type': 'multipart/form-data'
992 }
993}).then(({data}) => console.log(data));
994```
995
996In the `node.js` build, the ([`form-data`](https://github.com/form-data/form-data)) polyfill is used by default.
997
998You can overload the FormData class by setting the `env.FormData` config variable,
999but you probably won't need it in most cases:
1000
1001```js
1002const axios = require('axios');
1003var FormData = require('form-data');
1004
1005axios.post('https://httpbin.org/post', {x: 1, buf: new Buffer(10)}, {
1006 headers: {
1007 'Content-Type': 'multipart/form-data'
1008 }
1009}).then(({data}) => console.log(data));
1010```
1011
1012Axios FormData serializer supports some special endings to perform the following operations:
1013
1014- `{}` - serialize the value with JSON.stringify
1015- `[]` - unwrap the array-like object as separate fields with the same key
1016
1017> **Note**
1018> unwrap/expand operation will be used by default on arrays and FileList objects
1019
1020FormData serializer supports additional options via `config.formSerializer: object` property to handle rare cases:
1021
1022- `visitor: Function` - user-defined visitor function that will be called recursively to serialize the data object
1023to a `FormData` object by following custom rules.
1024
1025- `dots: boolean = false` - use dot notation instead of brackets to serialize arrays and objects;
1026
1027- `metaTokens: boolean = true` - add the special ending (e.g `user{}: '{"name": "John"}'`) in the FormData key.
1028The back-end body-parser could potentially use this meta-information to automatically parse the value as JSON.
1029
1030- `indexes: null|false|true = false` - controls how indexes will be added to unwrapped keys of `flat` array-like objects
1031
1032 - `null` - don't add brackets (`arr: 1`, `arr: 2`, `arr: 3`)
1033 - `false`(default) - add empty brackets (`arr[]: 1`, `arr[]: 2`, `arr[]: 3`)
1034 - `true` - add brackets with indexes (`arr[0]: 1`, `arr[1]: 2`, `arr[2]: 3`)
1035
1036Let's say we have an object like this one:
1037
1038```js
1039const obj = {
1040 x: 1,
1041 arr: [1, 2, 3],
1042 arr2: [1, [2], 3],
1043 users: [{name: 'Peter', surname: 'Griffin'}, {name: 'Thomas', surname: 'Anderson'}],
1044 'obj2{}': [{x:1}]
1045};
1046```
1047
1048The following steps will be executed by the Axios serializer internally:
1049
1050```js
1051const formData = new FormData();
1052formData.append('x', '1');
1053formData.append('arr[]', '1');
1054formData.append('arr[]', '2');
1055formData.append('arr[]', '3');
1056formData.append('arr2[0]', '1');
1057formData.append('arr2[1][0]', '2');
1058formData.append('arr2[2]', '3');
1059formData.append('users[0][name]', 'Peter');
1060formData.append('users[0][surname]', 'Griffin');
1061formData.append('users[1][name]', 'Thomas');
1062formData.append('users[1][surname]', 'Anderson');
1063formData.append('obj2{}', '[{"x":1}]');
1064```
1065
1066Axios supports the following shortcut methods: `postForm`, `putForm`, `patchForm`
1067which are just the corresponding http methods with the `Content-Type` header preset to `multipart/form-data`.
1068
1069## Files Posting
1070
1071You can easily submit a single file:
1072
1073```js
1074await axios.postForm('https://httpbin.org/post', {
1075 'myVar' : 'foo',
1076 'file': document.querySelector('#fileInput').files[0]
1077});
1078```
1079
1080or multiple files as `multipart/form-data`:
1081
1082```js
1083await axios.postForm('https://httpbin.org/post', {
1084 'files[]': document.querySelector('#fileInput').files
1085});
1086```
1087
1088`FileList` object can be passed directly:
1089
1090```js
1091await axios.postForm('https://httpbin.org/post', document.querySelector('#fileInput').files)
1092```
1093
1094All files will be sent with the same field names: `files[]`.
1095
1096## 🆕 HTML Form Posting (browser)
1097
1098Pass HTML Form element as a payload to submit it as `multipart/form-data` content.
1099
1100```js
1101await axios.postForm('https://httpbin.org/post', document.querySelector('#htmlForm'));
1102```
1103
1104`FormData` and `HTMLForm` objects can also be posted as `JSON` by explicitly setting the `Content-Type` header to `application/json`:
1105
1106```js
1107await axios.post('https://httpbin.org/post', document.querySelector('#htmlForm'), {
1108 headers: {
1109 'Content-Type': 'application/json'
1110 }
1111})
1112```
1113
1114For example, the Form
1115
1116```html
1117<form id="form">
1118 <input type="text" name="foo" value="1">
1119 <input type="text" name="deep.prop" value="2">
1120 <input type="text" name="deep prop spaced" value="3">
1121 <input type="text" name="baz" value="4">
1122 <input type="text" name="baz" value="5">
1123
1124 <select name="user.age">
1125 <option value="value1">Value 1</option>
1126 <option value="value2" selected>Value 2</option>
1127 <option value="value3">Value 3</option>
1128 </select>
1129
1130 <input type="submit" value="Save">
1131</form>
1132```
1133
1134will be submitted as the following JSON object:
1135
1136```js
1137{
1138 "foo": "1",
1139 "deep": {
1140 "prop": {
1141 "spaced": "3"
1142 }
1143 },
1144 "baz": [
1145 "4",
1146 "5"
1147 ],
1148 "user": {
1149 "age": "value2"
1150 }
1151}
1152````
1153
1154Sending `Blobs`/`Files` as JSON (`base64`) is not currently supported.
1155
1156## 🆕 Progress capturing
1157
1158Axios supports both browser and node environments to capture request upload/download progress.
1159
1160```js
1161await axios.post(url, data, {
1162 onUploadProgress: function (axiosProgressEvent) {
1163 /*{
1164 loaded: number;
1165 total?: number;
1166 progress?: number; // in range [0..1]
1167 bytes: number; // how many bytes have been transferred since the last trigger (delta)
1168 estimated?: number; // estimated time in seconds
1169 rate?: number; // upload speed in bytes
1170 upload: true; // upload sign
1171 }*/
1172 },
1173
1174 onDownloadProgress: function (axiosProgressEvent) {
1175 /*{
1176 loaded: number;
1177 total?: number;
1178 progress?: number;
1179 bytes: number;
1180 estimated?: number;
1181 rate?: number; // download speed in bytes
1182 download: true; // download sign
1183 }*/
1184 }
1185});
1186```
1187
1188You can also track stream upload/download progress in node.js:
1189
1190```js
1191const {data} = await axios.post(SERVER_URL, readableStream, {
1192 onUploadProgress: ({progress}) => {
1193 console.log((progress * 100).toFixed(2));
1194 },
1195
1196 headers: {
1197 'Content-Length': contentLength
1198 },
1199
1200 maxRedirects: 0 // avoid buffering the entire stream
1201});
1202````
1203
1204> **Note:**
1205> Capturing FormData upload progress is currently not currently supported in node.js environments.
1206
1207> **⚠️ Warning**
1208> It is recommended to disable redirects by setting maxRedirects: 0 to upload the stream in the **node.js** environment,
1209> as follow-redirects package will buffer the entire stream in RAM without following the "backpressure" algorithm.
1210
1211
1212## 🆕 Rate limiting
1213
1214Download and upload rate limits can only be set for the http adapter (node.js):
1215
1216```js
1217const {data} = await axios.post(LOCAL_SERVER_URL, myBuffer, {
1218 onUploadProgress: ({progress, rate}) => {
1219 console.log(`Upload [${(progress*100).toFixed(2)}%]: ${(rate / 1024).toFixed(2)}KB/s`)
1220 },
1221
1222 maxRate: [100 * 1024], // 100KB/s limit
1223});
1224```
1225
1226## Semver
1227
1228Until axios reaches a `1.0` release, breaking changes will be released with a new minor version. For example `0.5.1`, and `0.5.4` will have the same API, but `0.6.0` will have breaking changes.
1229
1230## Promises
1231
1232axios depends on a native ES6 Promise implementation to be [supported](https://caniuse.com/promises).
1233If your environment doesn't support ES6 Promises, you can [polyfill](https://github.com/jakearchibald/es6-promise).
1234
1235## TypeScript
1236
1237axios includes [TypeScript](https://typescriptlang.org) definitions and a type guard for axios errors.
1238
1239```typescript
1240let user: User = null;
1241try {
1242 const { data } = await axios.get('/user?ID=12345');
1243 user = data.userDetails;
1244} catch (error) {
1245 if (axios.isAxiosError(error)) {
1246 handleAxiosError(error);
1247 } else {
1248 handleUnexpectedError(error);
1249 }
1250}
1251```
1252
1253## Online one-click setup
1254
1255You can use Gitpod, an online IDE(which is free for Open Source) for contributing or running the examples online.
1256
1257[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/axios/axios/blob/main/examples/server.js)
1258
1259
1260## Resources
1261
1262* [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
1263* [Upgrade Guide](https://github.com/axios/axios/blob/master/UPGRADE_GUIDE.md)
1264* [Ecosystem](https://github.com/axios/axios/blob/master/ECOSYSTEM.md)
1265* [Contributing Guide](https://github.com/axios/axios/blob/master/CONTRIBUTING.md)
1266* [Code of Conduct](https://github.com/axios/axios/blob/master/CODE_OF_CONDUCT.md)
1267
1268## Credits
1269
1270axios is heavily inspired by the [$http service](https://docs.angularjs.org/api/ng/service/$http) provided in [AngularJS](https://angularjs.org/). Ultimately axios is an effort to provide a standalone `$http`-like service for use outside of AngularJS.
1271
1272## License
1273
1274[MIT](LICENSE)