介绍

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

  • 从浏览器中创建 XMLHttpRequests
  • node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

get请求

axios.get('/user', {params: {ID: 1111}})
.then(function (response) {
  console.log(response);
})
.catch(function (error) {
  console.log(error);
});

// 还可以这么写,es7新特性async/await 
async function getUser() {
  try {
    const response = await axios.get('/user?ID=1111');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

*async用于声明一个函数是异步的,而await是“等待”的意思,就是用于等待异步完成。
await只能在async函数中使用。
await可以让js进行等待,直到一个promise执行并返回它的结果,js才会继续往下执行。
async/await 面试经常问到哦,百度查一下,划重点

post请求

axios.post('/user', {firstName: 'xiliDong',lastName: 'dongxili'})
.then(function (response) {
  console.log(response);
})
.catch(function (error) {
  console.log(error);
});
//或者这样写
axios({
  method: 'post',
  url: '/user',
  data: {
    firstName: 'xiliDong',
    lastName: 'dongxili'
  }
});

执行多个并发请求

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: '请求地址前缀',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

响应结构:

{
  data: {},    // data由服务器提供的响应
  status: 200,  // 服务器响应的 HTTP 状态码
  statusText: 'OK',   // 服务器响应的 HTTP 状态信息
  headers: {},    // 服务器响应的头
  config: {}     // 为请求提供的配置信息
}

使用 then 时,你将接收下面这样的响应:
axios.get('/user/1111')
  .then(function(response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
  });

指定配置的默认值:

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

自定义实例默认值:

// 创建实例时设置配置的默认值
var instance = axios.create({
  baseURL: 'https://api.example.com'
});
// 在实例已创建后修改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

拦截器:

// request拦截器
import axios from 'axios'
import router from '../router'
// 创建axios实例
const service = axios.create({
  timeout: null // 请求超时时间
})
let serviceTips = '服务器超时'

// request拦截器
service.interceptors.request.use(
  config => {
    // console.log(service.interceptors)
    // 获取本地token
    let token = localStorage.getItem('tokendata')
    // 设置请求头
    let headers = 'application/json'
    // 是否携带token
    let tokenFlag = true
    // 是否修改请求信息
    if (config.opts) {
      // 获取携带token状态
      tokenFlag = config.opts ? config.opts.token : true
      // 获取请求头
      headers = config.opts.Header ? config.opts.Header : 'application/json'
      // 拓展头部参数
      let Head = config.opts.Head
      if (Head) {
        for (let key in Head) {
          config.headers[key] = Head[key]
        }
      }
    }
    // 暂时不加入token验证
    // if (token && tokenFlag) {
    //   // 条件允许,携带token请求
    //   config.headers['JSESSIONID'] = token
    //   // config.headers['X-Auth0-Token'] = token
    // } else {
    //   headers = 'application/x-www-form-urlencoded'
    // }
    // 设置请求格式
    config.headers['Content-Type'] = headers
    return config
  },
  err => {
    return Promise.reject(err)
  }
)

// http response 服务器响应拦截器
service.interceptors.response.use(
  response => {
    return response
  },
  error => {
    if (error.response) {
      switch (error.response.status) {
        case 401:
          error.response.data = '登陆超时,重新登陆'
          router.replace({
            path: '/login',
            query: {
              redirect: router.currentRoute.fullPath
            } // 登录成功后跳入浏览的当前页面
          })
          break
        case 404:
          error.response.data = '资源不存在'
          break
        case 406:
          error.response.data = '头部无携带token'
          break
        case 412:
          // 拦截错误 并重新跳入登页重新获取token
          router.replace({
            path: '/login',
            query: {
              redirect: router.currentRoute.fullPath
            } // 登录成功后跳入浏览的当前页面
          })
          error.response.data = '秘钥失效'
          localStorage.removeItem('tokendata') // 清除token
          break
        case 415:
          error.response.data = '请求type有误'
          break
        case 500:
          error.response.data = '服务器异常'
          break
      }
      serviceTips = error.response.data
    }
    Message.error(serviceTips)
    return Promise.reject(serviceTips)
  }
)
export default service

配置好后使用:

在api.js中引入拦截器:
import fetch from '@/utils/fetch' // 拦截器
export function getList(obj) {
  const data = obj
  return fetch({
    url:  '',
    method: 'POST',
    data
  })
}

--------------------------------
可以使用 validateStatus 配置选项定义一个自定义 HTTP 状态码的错误范围。
export function getList(obj) {
  const data = obj
  return fetch({
    url:  '',
    method: 'POST',
    validateStatus: function(status) {
      // return status >= 200 && status < 300; // 默认的
      return status < 500; // 状态码在大于或等于500时才会 reject
    },
    data
  })
}

重点

axios的请求头默认为'application/json',
即axios会默认序列化 JavaScript 对象为 JSON. 
如果想使用 application/x-www-form-urlencoded 格式,你可以使用下面的配置:
import Qs from 'qs'

export function getList(obj) {
  const data = Qs.stringify(obj)
  return fetch({
    url:  '',
    method: 'POST',
    headers: {
      'content-type': 'application/x-www-form-urlencoded',
       // 如果需要XMLHttpRequest,加入这个
       'X-Requested-With': 'XMLHttpRequest'
    },
    data
  })
}

单页面使用

import {getList} from '@/api/base.js'
// param为前端传入的参数
getList(param).then(res => {
  if (res.data.code === 0) {
    //获取成功业务代码
  } else {
    this.$message({
      message: `[${res.data.msg}]:查询失败`,
      type: "error"
    });
  }
})
.catch(() => {})

移除拦截器

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

取消请求

可以使用 CancelToken.source 工厂方法创建 cancel token

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

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

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

还可以通过传递一个 executor 函数到 CancelToken
的构造函数来创建 cancel token:

var CancelToken = axios.CancelToken;
var cancel;

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

// 取消请求
cancel();

注意,还可以使用同一个 cancel token 取消多个请求

点击前往参考地址