[Vue] Axios of Family Bucket

overview

Axios is a promise-based network request library that can run in nodejs and browsers. It is isomorphic, which means that the same set of code can run in both browsers and nodejs. Axios uses the native nodejs http module on the server side, but uses xmlhttprequests in the client browser, which is essentially an encapsulation of XHR, but an implementation version of promise

Promise
is an object, which is mainly used for asynchronous calculations, queues asynchronous operations, executes them in the desired order, and returns the expected results.

It means promise, you will get a result after a period of time, there are three states, pending, fulfilled, rejected waiting, success, failure state, if the state changes, it will trigger the response function in then() to handle the follow-up, which solves the callback hell , also supports multiple concurrent requests

const axios = require('axios');

// 向给定ID的用户发起请求
axios.get('/user?ID=12345')
  .then(function (response) {
    
    
    // 处理成功情况
    console.log(response);
  })
  .catch(function (error) {
    
    
    // 处理错误情况
    console.log(error);
  })
  .then(function () {
    
    
    // 总是会执行
  });

axios features

Create XMLHttpRequests from the browser

Create http request from node.js

Support Promise API

Intercept requests and responses

Transform request and response data

cancel request

Automatically convert JSON data

Client supports defense against XSRF

Install

Use npm:

$ npm install axios

Use bower:

$ bower install axios

Use yarn:

$ yarn add axios

Using the jsDelivr CDN:

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

Using the unpkg CDN:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

About ajax, fetch, axios

Using native js is still relatively cumbersome. In practice, libraries such as jquery are used. The encapsulated ajax request method is very useful, but the entire project is large, and it is not reasonable to introduce jquery to simply use ajax

Axios is designed for modern browsers, with simple design, simple API, and can be integrated with various front-end frameworks. It is a kind of encapsulation of ajax technology based on promise, just like jquery implements ajax encapsulation. There are many ways to implement ajax, and axios is one of them kind

Ajax is the abbreviation of Asynchronous JavaScript and XML, which means asynchronous network request. The biggest feature is that there is no refresh request data on the page. In the past, when the page form submitted data, after the user clicked the submit button, the page would be forced to refresh, and the experience was not good. But for mvc programming itself, for the current wave of mvvm is not going well, based on XHR development, there is also a fetch alternative

Implement an ajax request in the browser:
insert image description here
Fetch is a new technology product of front-end development

The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch() method that provides an easy, sensible way to fetch resources asynchronously across the network. This functionality was previously implemented using XMLHttpRequest. Fetch provides a better alternative that can easily be used by other technologies such as Service Workers. Fetch also provides a single logical place to define other HTTP related concepts such as CORS and extensions to HTTP.

fetch represents a more advanced technical direction, but the current compatibility is not very good, so be cautious when using it in projects

Axios API

You can pass relevant configuration to axios to create requests

axios(config)

// 发起一个post请求
axios({
    
    
  method: 'post',
  url: '/user/12345',
  data: {
    
    
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
// 在 node.js 用GET请求获取远程图片
axios({
    
    
  method: 'get',
  url: 'http://bit.ly/2mTM3nY',
  responseType: 'stream'
})
  .then(function (response) {
    
    
    response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
  });

axios(url[, config])

// 发起一个 GET 请求 (默认请求方式)
axios('/user/12345');

For convenience, aliases have been provided for all supported request methods.

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

Axios instance

Create an instance
You can create a new instance with a custom configuration.

axios.create([config])
const instance = axios.create({
    
    
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {
    
    'X-Custom-Header': 'foobar'}
});

Instance Methods
The following are the available instance methods. The specified configuration will be merged with the instance's configuration.

axios#request(config)
axios#get(url[, config])
axios#delete(url[, config])
axios#head(url[, config])
axios#options(url[, config])
axios#post(url[, data[, config]])
axios#put(url[, data[, config]])
axios#patch(url[, data[, config]])
axios#getUri([config])

request configuration

These are the configuration options available when creating a request. Only url is required. If no method is specified, the request will default to the GET method.

{
    
    
  // `url` 是用于请求的服务器 URL
  url: '/user',

  // `method` 是创建请求时使用的方法
  method: 'get', // 默认值

  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL: 'https://some-domain.com/api/',

  // `transformRequest` 允许在向服务器发送前,修改请求数据
  // 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法
  // 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream
  // 你可以修改请求头。
  transformRequest: [function (data, headers) {
    
    
    // 对发送的 data 进行任意转换处理

    return data;
  }],

  // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
    
    
    // 对接收的 data 进行任意转换处理

    return data;
  }],

  // 自定义请求头
  headers: {
    
    'X-Requested-With': 'XMLHttpRequest'},

  // `params` 是与请求一起发送的 URL 参数
  // 必须是一个简单对象或 URLSearchParams 对象
  params: {
    
    
    ID: 12345
  },

  // `paramsSerializer`是可选方法,主要用于序列化`params`
  // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  paramsSerializer: function (params) {
    
    
    return Qs.stringify(params, {
    
    arrayFormat: 'brackets'})
  },

  // `data` 是作为请求体被发送的数据
  // 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
  // 在没有设置 `transformRequest` 时,则必须是以下类型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器专属: FormData, File, Blob
  // - Node 专属: Stream, Buffer
  data: {
    
    
    firstName: 'Fred'
  },
  
  // 发送请求体数据的可选语法
  // 请求方式 post
  // 只有 value 会被发送,key 则不会
  data: 'Country=Brasil&City=Belo Horizonte',

  // `timeout` 指定请求超时的毫秒数。
  // 如果请求时间超过 `timeout` 的值,则请求会被中断
  timeout: 1000, // 默认值是 `0` (永不超时)

  // `withCredentials` 表示跨域请求时是否需要使用凭证
  withCredentials: false, // default

  // `adapter` 允许自定义处理请求,这使测试更加容易。
  // 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。
  adapter: function (config) {
    
    
    /* ... */
  },

  // `auth` HTTP Basic Auth
  auth: {
    
    
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // `responseType` 表示浏览器将要响应的数据类型
  // 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
  // 浏览器专属:'blob'
  responseType: 'json', // 默认值

  // `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
  // 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
  // Note: Ignored for `responseType` of 'stream' or client-side requests
  responseEncoding: 'utf8', // 默认值

  // `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
  xsrfCookieName: 'XSRF-TOKEN', // 默认值

  // `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称
  xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值

  // `onUploadProgress` 允许为上传处理进度事件
  // 浏览器专属
  onUploadProgress: function (progressEvent) {
    
    
    // 处理原生进度事件
  },

  // `onDownloadProgress` 允许为下载处理进度事件
  // 浏览器专属
  onDownloadProgress: function (progressEvent) {
    
    
    // 处理原生进度事件
  },

  // `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数
  maxContentLength: 2000,

  // `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数
  maxBodyLength: 2000,

  // `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise。
  // 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
  // 则promise 将会 resolved,否则是 rejected。
  validateStatus: function (status) {
    
    
    return status >= 200 && status < 300; // 默认值
  },

  // `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
  // 如果设置为0,则不会进行重定向
  maxRedirects: 5, // 默认值

  // `socketPath` 定义了在node.js中使用的UNIX套接字。
  // e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。
  // 只能指定 `socketPath` 或 `proxy` 。
  // 若都指定,这使用 `socketPath` 。
  socketPath: null, // default

  // `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
  // and https requests, respectively, in node.js. This allows options to be added like
  // `keepAlive` that are not enabled by default.
  httpAgent: new http.Agent({
    
     keepAlive: true }),
  httpsAgent: new https.Agent({
    
     keepAlive: true }),

  // `proxy` 定义了代理服务器的主机名,端口和协议。
  // 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。
  // 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
  // `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。
  // 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
  // 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`
  proxy: {
    
    
    protocol: 'https',
    host: '127.0.0.1',
    port: 9000,
    auth: {
    
    
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // see https://axios-http.com/zh/docs/cancellation
  cancelToken: new CancelToken(function (cancel) {
    
    
  }),

  // `decompress` indicates whether or not the response body should be decompressed 
  // automatically. If set to `true` will also remove the 'content-encoding' header 
  // from the responses objects of all decompressed responses
  // - Node only (XHR cannot turn off decompression)
  decompress: true // 默认值

}

response structure

A response to a request contains the following information.

{
    
    
  // `data` 由服务器提供的响应
  data: {
    
    },

  // `status` 来自服务器响应的 HTTP 状态码
  status: 200,

  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: 'OK',

  // `headers` 是服务器响应头
  // 所有的 header 名称都是小写,而且可以使用方括号语法访问
  // 例如: `response.headers['content-type']`
  headers: {
    
    },

  // `config` 是 `axios` 请求的配置信息
  config: {
    
    },

  // `request` 是生成此响应的请求
  // 在node.js中它是最后一个ClientRequest实例 (in redirects),
  // 在浏览器中则是 XMLHttpRequest 实例
  request: {
    
    }
}

When using then, you will receive a response like this:

axios.get('/user/12345')
  .then(function (response) {
    
    
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
  });

When using catch, or passing a rejection callback as the second argument of then, the response is available through the error object. as explained in the error handling section.

default allocation

Default Configuration
You can specify a default configuration, which will be applied to every request.

Global axios defaults

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

Custom instance defaults

// 创建实例时配置默认值
const instance = axios.create({
    
    
  baseURL: 'https://api.example.com'
});

// 创建实例后修改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

Priority of configurations
Configurations will be merged by priority. Its order is: the library defaults found in lib/defaults.js, then the instance's defaults attribute, and finally the request's config parameter. The later ones take precedence over the earlier ones. Below is an example.

// 使用库提供的默认配置创建实例
// 此时超时配置的默认值是 `0`
const instance = axios.create();

// 重写库的超时默认值
// 现在,所有使用此实例的请求都将等待2.5秒,然后才会超时
instance.defaults.timeout = 2500;

// 重写此请求的超时时间,因为该请求需要很长时间
instance.get('/longRequest', {
    
    
  timeout: 5000
});

interceptor

Intercept requests or responses before they are processed by then or catch.

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    
    
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    
    
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    
    
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, function (error) {
    
    
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  });

If you need to remove the interceptor later, you can do this:

const myInterceptor = axios.interceptors.request.use(function () {
    
    /*...*/});
axios.interceptors.request.eject(myInterceptor);

Interceptors can be added to custom axios instances.

const instance = axios.create();
instance.interceptors.request.use(function () {
    
    /*...*/});

error handling

axios.get('/user/12345')
  .catch(function (error) {
    
    
    if (error.response) {
    
    
      // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
    
    
      // 请求已经成功发起,但没有收到响应
      // `error.request` 在浏览器中是 XMLHttpRequest 的实例,
      // 而在node.js中是 http.ClientRequest 的实例
      console.log(error.request);
    } else {
    
    
      // 发送请求时出了点问题
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

Using the validateStatus configuration option, you can customize the HTTP code that throws an error.

axios.get('/user/12345', {
    
    
  validateStatus: function (status) {
    
    
    return status < 500; // 处理状态码小于500的情况
  }
})

Use toJSON to get more information about HTTP errors.

axios.get('/user/12345')
  .catch(function (error) {
    
    
    console.log(error.toJSON());
  });

cancel request

AbortController
Starting from v0.22.0, Axios supports the fetch API method - AbortController to cancel the request:

const controller = new AbortController();

axios.get('/foo/bar', {
    
    
   signal: controller.signal
}).then(function(response) {
    
    
   //...
});
// 取消请求
controller.abort()

CancelToken deprecated
You can also use the cancel token to cancel a request.

Axios' cancel token API is based on cancelable promises proposals.

This API has been deprecated since v0.22.0 and should not be used in new projects.

A cancel token can be created using the CancelToken.source factory method as follows:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
    
    
  cancelToken: source.token
}).catch(function (thrown) {
    
    
  if (axios.isCancel(thrown)) {
    
    
    console.log('Request canceled', thrown.message);
  } else {
    
    
    // 处理错误
  }
});

axios.post('/user/12345', {
    
    
  name: 'new name'
}, {
    
    
  cancelToken: source.token
})

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
也可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建一个 cancel token:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
    
    
  cancelToken: new CancelToken(function executor(c) {
    
    
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// 取消请求
cancel();

Note: Multiple requests can be canceled with the same cancel token or signal.

In the interim, you can use both cancellation APIs, even for the same request:

const controller = new AbortController();

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
    
    
  cancelToken: source.token,
  signal: controller.signal
}).catch(function (thrown) {
    
    
  if (axios.isCancel(thrown)) {
    
    
    console.log('Request canceled', thrown.message);
  } else {
    
    
    // 处理错误
  }
});

axios.post('/user/12345', {
    
    
  name: 'new name'
}, {
    
    
  cancelToken: source.token
})

// 取消请求 (message 参数是可选的)
source.cancel('Operation canceled by the user.');
// 或
controller.abort(); // 不支持 message 参数

cancel request

By default, axios serializes JavaScript objects to JSON. To send data in application/x-www-form-urlencoded format, you can use one of the following options.

Browser
In a browser, the URLSearchParams API can be used as follows:

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

Note that not all browsers (see caniuse.com) support URLSearchParams, but polyfills are available (make sure to polyfill the global environment)

Alternatively, you can encode data using the qs library:

const qs = require('qs');
axios.post('/foo', qs.stringify({
    
     'bar': 123 }));
或者用另一种方式 (ES6),

import qs from 'qs';
const data = {
    
     'bar': 123 };
const options = {
    
    
  method: 'POST',
  headers: {
    
     'content-type': 'application/x-www-form-urlencoded' },
  data: qs.stringify(data),
  url,
};
axios(options);

Node.js
Query string
In node.js, you can use the querystring module as follows:

const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({
    
     foo: 'bar' }));

Or use 'URLSearchParams' from 'url module' like this:

const url = require('url');
const params = new url.URLSearchParams({
    
     foo: 'bar' });
axios.post('http://something.com/', params.toString());

You can also use the qs library.

NOTE
If you need to stringify nested objects, it's better to use the qs library, as the querystring method has known issues in that use case (https://github.com/nodejs/node-v0.x-archive/ issues/1665).

Form data
In node.js, you can use the form-data library as follows:

const FormData = require('form-data');
 
const form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));

axios.post('https://example.com', form, {
    
     headers: form.getHeaders() })

Alternatively, use an interceptor:

axios.interceptors.request.use(config => {
    
    
  if (config.data instanceof FormData) {
    
    
    Object.assign(config.headers, config.data.getHeaders());
  }
  return config;
});

request body encoding

Axios Chinese document
front-end basic series (1) Axios

Guess you like

Origin blog.csdn.net/weixin_44231544/article/details/132333585