浅析Axios的特性和用法

411 阅读3分钟

Vue2.0之后,axios开始受到更多的欢迎。其实axios也是对原生XHR的一种封装,不过是Promise实现版本。它是一个用于浏览器和 nodejs 的 HTTP 客户端,符合最新的ES规范。

axios具有以下特征:

  1. 从浏览器中创建 XMLHttpRequest
  2. 支持 Promise API
  3. 客户端支持防止CSRF
  4. 提供了一些并发请求的接口
  5. 从 node.js 创建 http 请求
  6. 拦截请求和响应
  7. 转换请求和响应数据
  8. 取消请求
  9. 自动转换JSON数据

PS:防止CSRF:就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。

设置全局的 axios 默认值

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'
注:axios 的 headers的 content-type 默认是 “application/json ”

默认情况下,axios将JavaScript对象序列化为JSON,如果是get请求,对请求参数不用做任何处理,但是如果是post请求,并且Content-Type 为application/x-www-form-urlencoded,需要使用URLSearchParams API格式化请求参数, 否则Content-Type依然是application/json

var params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');

get请求,以下3中写法完全等价

// 第一种写法
axios.get('/user?id=12345&name=xiaoming')
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

// 第二种写法
axios.get('/user', {
    params: {
      id: '12345'name: 'xiaoming'
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

// 第三种写法
axios({
    url: '/user',
    method: 'get',
    params: {
      id: '12345'name: 'xiaoming'
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

post请求,以下2种写法完全等价

// 第一种写法
axios({
    url: '/user',
    method: 'post',
    headers: {
        'Content-Type': 'application/json'
    },
    data: {
      id: '12345'name: 'xiaoming'
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

// 第二种写法
var url = '/user';
var data = {
      id: '12345'name: 'xiaoming'
    };
axios.post(url, data, {
       headers: {
        'Content-Type': 'application/json'
    }
})
.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');
}
 
axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
}));

创建实例

可以使用自定义配置新建一个 axios 实例

axios.create([config])

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

配置会以一个优先顺序进行合并,顺序由低到高为

  1. 在 node_modules/axios/lib/defaults.js 找到的库的默认值
  2. 实例的 defaults 属性
  3. 请求的 config 参数
// 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();
 
// 覆写库的超时默认值
// 现在,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;
 
// 为已知需要花费很长时间的请求覆写超时设置
instance.get('/longRequest', {
  timeout: 5000
});

拦截器

在请求发出之前或响应被 then 或 catch 处理前拦截它们做预处理。

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
  }, function (error) {
    // 对请求错误做些什么
  });
 
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
  }, function (error) {
    // 对响应错误做点什么
  });

可以在稍后移除拦截器:

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

可以为自定义 axios 实例添加拦截器

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