「参考」axios指南

618 阅读7分钟

什么是 axios?

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

特性

从浏览器创建XMLHttpRequests

node.js创建HTTP请求

支持Promise API

拦截请求和响应

转换请求数据和响应数据

取消请求

自动转换JSON数据

客户端支持防御XSRF

安装

使用 npm:

$ npm install axios

使用 bower:

$ bower install axios

使用 yarn:

$ yarn add axios

使用 jsDelivr CDN:

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

使用 unpkg CDN:

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

例子

注:CommonJS usage

为了在将CommonJS导入与require()一起使用时获得TypeScript类型(用于智能提示/自动补全),请使用以下方法:

const axios = require('axios').default;

// axios.<method> will now provide autocomplete and parameter typings

Get请求

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.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    // 继续执行
  });  

// 需要使用async和await? 添加 `async` 关键字到函数外面
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

async和await是ES2017的语法可能不适用于IE或者更早版本的浏览器,请谨慎使用

POST请求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

执行多个合并请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

Promise.all([getUserAccount(), getUserPermissions()])
  .then(function (results) {
    const acct = results[0];
    const perm = results[1];
  });

API

可以通过将相关配置传递给axios来发出请求。

axios(config)

// 发送POST请求
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
//在node.js中获取远程图像的请求
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');

请求方法别名

为了方便起见,已为所有受支持的请求方法提供了别名

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]])

使用别名方法时,无需在config中指定url,method和data属性。

创建实例

您可以使用自定义配置创建axios的新实例。

axios.create([config])

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

实例方法

可用的实例方法在下面列出。 指定的配置将与实例配置合并。

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])

配置config选项

这些是发出请求的可用配置选项。 仅URL是必需的。 如果未指定method,则请求将默认为GET。

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

  // `method` 发出请求时的方法
  method: 'get', // 默认是get

  // 除非`url`是绝对的,否则`baseURL`将前置于`url`。
  // 为axios实例设置`baseURL`以传递相对URL的方式非常方便
  // 写法如下
  baseURL: 'https://some-domain.com/api/',

  // `transformRequest`允许在将请求数据发送到服务器之前对其进行转化
  // 这仅适用于“ PUT”,“ POST”,“ PATCH”和“ DELETE”请求method
  // 数组中的最后一个函数必须返回字符串或Buffer,ArrayBuffer的实例或FormData或 Stream
  // 此外你也可能需要设置下headers对象
  transformRequest: [function (data, headers) {
    // 在这里处理数据

    return data;
  }],

  // `transformResponse`允许在响应之前更改数据
  // 它会把数据传递给 then或者catch
  transformResponse: [function (data) {
    // 在这里做数据操作

    return data;
  }],

  // `headers`是自定义的要被发送的信息头
  headers: {'X-Requested-With': 'XMLHttpRequest'},

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

  // `paramsSerializer`是一个可选的函数,用来控制和序列化参数
  // (例如 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方法
  // 键不会被发送,只有值会被发送
  data: 'Country=Brasil&City=Belo Horizonte',

  // `timeout`定义请求的时间,单位是毫秒。
  // 如果请求所花的时间超过这个时间,则该请求将被中止
  timeout: 1000, // 默认 为 `0` (no timeout)

 //`withCredentials`表明跨跨域请求书否需要证明。
  withCredentials: false, // default

  //`adapter`适配器,允许自定义处理请求,这会使测试更简单。
  //返回一个promise,并且提供一个有效的相应。(查看[response docs](#response-api))
  adapter: function (config) {
    /* ... */
  },

  //`auth`表明HTTP基础的认证应该被使用,并且提供证书。
  //这个会设置一个`authorization` 头(header),并且覆盖你在header设置的Authorization头信息
  //请注意,只能通过此参数配置HTTP Basic身份验证。
  // 对于Bearer令牌等,请改用`Authorization`自定义标头。
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  //`responsetype`表明服务器返回的数据类型,这些类型的设置应该是
  //'arraybuffer','blob','document','json','text',stream'
 
  responseType: 'json', // default

  //`responseEncoding`表明解析相应的编码方式。
  //**注意**会忽视responseType为stream或者客户端的请求
  responseEncoding: 'utf8', // default

 //`xsrfCookieName`时cookie做xsrf会话时的名字。

  xsrfCookieName: 'XSRF-TOKEN', // 默认值

  // `xsrfHeaderName` 是http头(header)的名字,并且该头携带xsrf的值
  xsrfHeaderName: 'X-XSRF-TOKEN', // default

  //`onUploadProgress`允许处理上传过程的进程事件
  // browser only
  onUploadProgress: function (progressEvent) {
    //本地过程事件发生时想做的事
  },

  //`onDownloadProgress`允许处理下载过程的进程事件
  // browser only
  onDownloadProgress: function (progressEvent) {
    //下载过程中想做的事
  },

  //`maxContentLength` 定义http返回内容的最大字节容量
  maxContentLength: 2000,

  // “ maxBodyLength”(仅“节点”选项)定义http请求内容的最大容量(以字节为单位)
  maxBodyLength: 2000,

  //`validateStatus` 定义promise的resolve和reject。
  // http返回状态码,如果`validateStatus`返回true(或者设置成null/undefined),promise将会resolve;其他的promise将reject
  validateStatus: function (status) {
    return status >= 200 && status < 300; // default
  },

  //`maxRedirect`定义重导向到node.js中的最大数量。
  //如果值为0,那么没有redirect。
  maxRedirects: 5, // default

  //`socketPath`定义一个在node.js中使用的 `UNIX Socket`。.
  //例如 '/var/run/docker.sock' to send requests to the docker daemon.
  // `socketPath`和`proxy`只可定义其一.
  // 如果都定义则只会使用`socketPath`.
  socketPath: null, // default

  // //`httpAgent` 和 `httpsAgent`当产生一个http或者https请求时分别定义一个自定义的代理在nodejs中。
  //  这个允许设置一些选项,像是`keepAlive`--这个在默认中是没有开启的.
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // `proxy`定义代理服务器的主机名,端口和协议.
  // 如果代理服务器使用HTTPS,则必须将协议设置为“ https”。. 
  proxy: {
    protocol: 'https',
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // `cancelToken`指定一个取消令牌,可用于取消请求
 //(有关详细信息,请参见下面的“取消”部分
  cancelToken: new CancelToken(function (cancel) {
  }),

  // decompress指示是否应对响应主体进行自动解压缩 
  //  如果设置为“ true”,还将删除来自所有解压缩响应的响应对象“ content-encoding”标头 
  // - Node only (XHR 无法关闭解压缩)
  decompress: true // default

}

Response Schema

请求的响应包含以下信息

{
  // `data` 是服务器的响应
  data: {},

 //`status`是服务器返回的http状态码
  status: 200,

  // `statusText` 是服务器响应中的HTTP状态消息
  statusText: 'OK',

  // `headers` the HTTP headers that the server responded with
  // 所有的header名都小写,并且加上[]进行访问.
  // Example: `response.headers['content-type']`
  headers: {},

  // `config`是对axios进行的设置,目的是为了请求(request)
  config: {},

  // `request`是获取当前响应的请求
  // 它是node.js中最后一次的 ClientRequest的实例(在redirect中)
  // 或者是在浏览器中的XMLHttpREquest实例
  request: {}
}

使用then时,您将收到如下响应:

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);
  });

当使用catch或将拒绝回调作为then的第二个参数传递时,响应将通过错误对象提供,如“处理错误”部分所述。

Config Defaults

我们可以指定将应用于每个请求的配置默认值。

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';

自定义实例默认值

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

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

配置优先级顺序

将以优先顺序合并。 顺序是在lib / defaults.js中找到库默认值,然后是实例的defaults属性,最后是请求的config参数。 后者将优先于前者。 这是一个例子。

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

// 覆盖默认的timeout
// 现在,使用此实例的所有请求将等待2.5秒
instance.defaults.timeout = 2500;

// 用更长的时间覆盖默认值
instance.get('/longRequest', {
  timeout: 5000
});

Interceptors拦截器

您可以先拦截请求或响应,然后再进行处理或捕获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);
  });

如果以后需要删除拦截器,则可以

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

您可以将拦截器添加到axios的自定义实例中。 ``js` const instance = axios.create(); instance.interceptors.request.use(function () {/.../});

# 错误处理
```js
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);
  });

使用validateStatus config选项,您可以定义引发错误的HTTP代码。

axios.get('/user/12345', {
  validateStatus: function (status) {
    return status < 500; // Resolve only if the status code is less than 500
  }
})

使用toJSON,您将获得一个对象,其中包含有关HTTP错误的更多信息

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

中止

你可以使用cancel token取消请求

您可以使用CancelToken.source工厂创建一个取消令牌,如下所示

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 {
    // handle error
  }
});

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

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

您还可以通过将执行程序函数传递给CancelToken构造函数来创建取消token。

const CancelToken = axios.CancelToken;
let 取消;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();

注意:您可以使用相同的cancel token取消多个请求。

使用application / x-www-form-urlencoded格式

默认情况下,axios将JavaScript对象序列化为JSON。 要改为以application / x-www-form-urlencoded格式发送数据,可以使用以下选项之一。

浏览器

在浏览器中,可以如下使用URLSearchParams API:

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

请注意,并非所有浏览器都支持URLSearchParams(请参见caniuse.com),但是有可用的polyfill(确保对全局环境进行polyfill)。

另外,您可以使用qs库对数据进行编码:

const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));

或者使用ES6的方式

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

Node.js

Query string

在node.js中,可以按以下方式使用querystring模块:

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

或“网址模块”中的“ URLSearchParams”,如下所示:

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

你也可以使用qs库

如果需要对嵌套对象进行字符串化处理,则最好使用qs库,因为querystring方法存在该用例的已知问题(github.com/nodejs/node…

Form data 在node.js中,您可以使用表单数据库,如下所示:

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() })

或者, 使用拦截器(interceptor):

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

Semver 在axios达到1.0版本之前,重大更改将以新的次要版本发布。 例如,0.5.1和0.5.4将具有相同的API,但是0.6.0将具有重大更改

Promises axios取决于要支持的本机ES6 Promise实现。 如果您的环境不支持ES6 Promises,则可以进行polyfill。

TypeScript

axios包括TypeScript定义。

import axios from 'axios';
axios.get('/user?ID=12345');