一起养成写作习气!这是我参加「日新方案 4 月更文应战」的第1天,点击检查活动概况。

不管任何前端项目都是离不开网络恳求。就前端恳求而言,axios是目前盛行的网络恳求,也是vue官方推荐运用的ajax库。把握它的根本运用是十分必要的,这篇文章将axios与vue项目结合做一个根本运用的总结,十分合适入门。

网络恳求开展史

要学习axios首要应该了解前端ajax恳求的大致开展。

1. 传统的Ajax
传统的Ajax恳求是根据XMLHttpRequest(XHR)目标。能够直接运用。但是运用起来装备较为费事,实践开发中运用十分少,在MVC年代一般运用的是JQuery-Ajax。相关于传统的Ajax现在运用更多的是Fetch恳求。

2. JQuery-Ajax
JQuery-Ajax在前端JQuery时,因为JQuery的强大兼容性在项目开发中$Ajax运用十分广泛,需求引入JQuery库,其底层原理也是对传统的Ajax,XHR目标进行封装。但是在前端结构MVVC年代,例如运用vue搭建项目,假如再继续运用$Ajax就还需再独自引入JQuery重量级1w+代码量的库是因小失大的。所以针关于结构的网络恳求应运而生。

3.axios
在Vue1.0年代,官方推出了Vue-resource,其体积相关于JQuery小的多,但是在Vue2.0年代官方宣布不再更新,那么继续运用Vue-resource就会存在版本无法匹配问题。因而在Vue2.0年代开端,官方推荐运用axios作为新一代的Ajax库。axios其长处:在浏览器中发送XMLHttpRequest恳求、在node中发送http恳求、支持Promise API、阻拦恳求和相应、转化恳求和呼应数据等,这儿不再一一描述,想进一步了解其长处,能够查询相关材料。

axios基本使用及封装

axios装置

先来看看axios的根本运用,本篇介绍axios的运用是与vue项目结合起来的,首要在命令行中输入npm create vue创立vue项目。其次,axios是一个第三方Ajax库,需求独自装置和引入,在命令行中输入npm install axios --save-D装置axios的依靠包。接着,在需求运用的当地引入axios目标import axios from axios,在实践开发中,一般会独自树立一个js文件引入axios引入再进行封装,下文会介绍。

axios根本运用

axios恳求办法

先来看看axios具体有哪些恳求办法:

  • axios(config)
  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]]) axios(config)恳求办法: axios接纳一个目标,在目标中运用键值对办法写入装备信息,get恳求下,默许method能够不写。
axios({
    url:'http://123.207.32.32:8000/home/multidata',
    params:{
        type:'pop',
        page:1
    }
}).then(res=>{
    console.log(res);
}).catch(err=>{
    console.log(err);
})

axios.request(config)恳求办法: 与axios(config)写法共同,都是接纳一个目标,在目标中运用键值对办法装备信息。

axios.request({
    url:'http://123.207.32.32:8000/home/multidata'
}).then(res=>{
    console.log(res);
}).catch(err=>{
    console.log(err);
})

axios.get(url[, config])恳求办法 :限定method为get恳求,网络恳求中get恳求是将参数拼接搭配url上发送的恳求,在axios恳求中则能够运用params特点装备将传递的参数拼接到url上。params特点是一个目标,其传递的参数运用键值对形式书写

axios.get('http://123.207.32.32:8000/home/multidata',{
  params:{
    type:'pop',page:1
    }
  }).then(res=>{
    console.log(res);
  }).catch(err=>{
    console.log(err);
  })

axios装备

常见装备项

  • 恳求地址url: '/user'
  • 恳求类型:method: 'get'
  • 请根途径:baseURL: 'http://www.mt.com/api'
  • 恳求前的数据处理transformRequest:[function(data){}]
  • 恳求后的数据处理: transformResponse: [function(data){}]
  • 自界说的恳求头:headers:{'x-Requested-With':'XMLHttpRequest'}
  • URL查询目标:params:{ id: 12 },
  • 查询目标序列化函数:paramsSerializer: function(params){ }
  • request body:data: { key: 'aa'}
  • 超时设置:timeout: 1000,
  • 跨域是否带Token:withCredentials: false
  • 自界说恳求处理:adapter: function(resolve, reject, config){}
  • 身份验证信息:auth: { uname: '', pwd: '12'}
  • 呼应的数据格式json / blob /document /arraybuffer / text / stream:responseType: 'json'

大局装备

第三方结构经过import axios from axios引入axios归于大局的axios。运用default关键字能够对axios进行一个装备。那么一切的axios恳求都会带着default预先界说好的默许设置。关于公共的恳求装备能够抽离出来,例如:恳求超时时刻、服务器地址、设置恳求头号

语法格式:axios实例.default.装备项

参阅代码:

// axios.defaults.装备项===》axios大局装备
axios.defaults.baseURL = 'http://123.207.32.32:8000'
axios.defaults.timeout = 5000
axios.defaults.headers['X-TOKEN'] = '123xxx'
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.responseType = 'blob' 
axios('home/multidata',
    {
        params: {
            type: 'pop',
            page: 1
        }
    }
).then(res => {
    console.log(res);
}).catch(err => {
    console.log(err);
})

axios并发恳求

有时分存在这样一种情况:一起发送多个恳求,而且等到多个恳求完结呼应并拿到呼应内容时分才会回来。这个时分就需求运用到并发恳求。axios.all()本质上便是promise.all()。
axios.all()接纳一个Array数组作为参数,每个参数成员便是要发送的axios恳求体,axios.all()函数回来一个promise实例,经过.then办法接纳呼应的数据,而且呼应的数据也包裹在一个Array数组中, 每个数组成员对应呼应的恳求成果。能够经过axios.spread()函数将回来的数组[res1,res2]打开为,res1,res2。留意,并发恳求假如有一个独自的恳求失利,那么axios.all()函数整个恳求就会报错,经过.catch()办法拿到报错信息。

axios.all([
    axios.get('http://123.207.32.32:8000/home/multidata', { params: { type: 'pop', page: 1 } }),
    axios({ url: 'http://123.207.32.32:8000/home/multidata', params: { type: 'pop', page: 1 } })
]).then(res => {
    console.log(res) // 回来的是数组包裹的呼应信息[res1,res2]
}).catch(err=>{
    console.log(err)
})
axios.all([
    axios.get('http://123.207.32.32:8000/home/multidata', { params: { type: 'pop', page: 1 } }),
    axios({ url: 'http://123.207.32.32:8000/home/multidata', params: { type: 'pop', page: 1 } })
]).then(axios.spread((res1,res2) => { // 运用axios。spread打开数组
    console.log(res1)
    console.log(res2)
})).catch(err=>{
    console.log(err)
})

创立axios实例

思考一下,咱们经过import axios from 'axios'引入了大局的axios目标,为什么还要再独自创立axios实例呢?

在实践项目开发中,咱们存在不同的恳求默许装备可能不一样,例如,服务器地址、恳求超时…默许装备不同,那么大局引入的axios再运用axios.default.装备项设置大局的默许一致的装备无法解决这个问题。因而,咱们运用axios.create()函数创立新的axios实例,不同的axios实例能够设置不同的默许装备,各个axios实例之间的装备是互不影响的。
axios.create()接纳一个目标参数,运用键值对传入默许的装备,回来axios实例。

import axios from 'axios'
// axios实例1
const axiosInstance1 = axios.create({
    baseURL:'http://123.207.32.32:8000',
    timeout:5000
})
axiosInstance1({
    url:'/home/multidata',
    params:{
        type:'pop',
        page:3
    }
}).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)
})
// axios实例2
const axiosInstance2 = axios.create({
    baseURL:'http://192.168.5.110:9001',
    timeout:5000
})
axiosInstance1({
    url:'/home/multidata'',
    params:{
        type:'pop',
        page:3
    }
})
.then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)
})

也能够对新创立的axios实例运用.default办法装备

import axios from 'axios'
// axios实例1
const axiosInstance1 = axios.create()
axiosInstance1.default.baseURL = 'http://123.207.32.32:8000'
axiosInstance1.default.timeout = 5000
axiosInstance1({
    url:'/home/multidata',
    params:{
        type:'pop',
        page:3
    }
}).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)
})

axios阻拦器

阻拦器望文生义即为阻拦,对一切的恳求和呼应进行阻拦。

办法:
axios.interceptor.request.use()恳求阻拦器
axios.interceptor.response.use()呼应阻拦器

两个阻拦器运用办法共同,都接纳两个参数:

  • 参数1:阻拦成功回调函数
  • 参数2:阻拦失利回调函数。 留意,不管恳求仍是呼应阻拦,阻拦完了要return 回来阻拦的恳求体和呼应体,不然就不会履行后边的恳求和呼应成果操作了。

可参axios照源码如下:

export interface AxiosInterceptorManager<V> {
  use<T = V>(onFulfilled?: (value: V) => T | Promise<T>, onRejected?: (error: any) => any): number;
  eject(id: number): void;
}

恳求阻拦器运用场景:

  • 发送恳求时增加‘正在加载中…’图标
  • 某些恳求有必要用户登陆,判断是否有用户token,没有跳转到登陆页
  • 对恳求的参数进行序列化
axios.interceptor.request.use(res=>{
    console.log('来到了request阻拦的success中');
    // 阻拦完了要回来
    return res
},err=>{
    console.log('来到了request阻拦的failure中');
})

呼应阻拦器运用场景:

  • 回来呼应的res.data数据成果
  • 根据呼应的status状况码,做出不同的操作。例如:假如status是401,呼应阻拦失利,那么一般是token失效,没有授权,要跳转至登陆页;status是200,呼应阻拦成功操作,回来res.data呼应数据
axios.interceptor.response.use(res=>{
    console.log('来到了response阻拦的success中');
    // 阻拦完了要回来
    return res.data
},err=>{
    console.log('来到了response阻拦的failure中');
})

axios封装

在项目中,咱们一般会对恳求进行二次封装,在项目中src/utils文件下新建request.js文件存放封装的恳求,导入第三方恳求库。那么为什么会二次封装恳求呢?因为例如axios恳求归于第三方库,假如后期作者不再维护axios库的时分,咱们只需求修改request.js文件依靠的第三方结构部分,这样不会影响项目中其他需求发送恳求的代码。


import axios from 'axios'
import { useMsgbox, Message } from 'element3'
import store from '@/store'
import { getToken } from '@/utils/auth'
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  timeout: 5000, // request timeout
})
service.interceptors.request.use(
  config => {
    if (store.getters.token) {
      config.headers['X-Token'] = getToken()
    }
    return config
  },
  error => {
    console.log(error) // for debug
    return Promise.reject(error)
  },
)
service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code !== 20000) {
      console.log('接口信息报错',res.message)
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    console.log('接口信息报错' + error) 
    return Promise.reject(error)
  },
)
export default service