一套全面又有实际意义的axios封装+api管理方案

e90866e7658d

axios+vuex

前言

功能点

此文主要是基于vuecli3项目中axios封装及api管理的实践记录及过程中的踩坑收获,功能基本都是根据工作中需求实现。需求背景是,在同一套请求配置下,实现以下主要功能:

  • 自定义请求配置
  • 设置全局拦截器
  • 响应成功及异常的全局拦截统一处理
  • 防止重复请求(取消当前重复的请求)
  • 路由切换取消当前所有pending状态的请求(可配置白名单)
  • 单独取消发出的某个请求
  • api统一管理

axios一些特性

在开始之前,首先明确一些axios的特性,这些特性会影响到某些功能的实现方式:

  1. 通过axios.create()方法创建的实例对象只有常见的数据请求方法,没有取消请求、并发请求等方法。可通过Object.keys()将所有的key打印出来对比得知。
  2. axios拦截器是可以累加的,每添加一个拦截器,就会返回一个对应的拦截器id,也就是无法通过新增拦截的方式覆盖或者改变已有拦截器的配置。但可以利用拦截器id通过axios.interceptors.request.eject(InterceptorId)方法移除指定拦截器。
  3. 对于同一个axios对象,如果全局拦截器中设置了CancelToken属性,就无法在单独的请求中再通过此属性取消请求。移除全局拦截器可以解决这个问题,但又会有另一个问题,拦截器移除后就永远失效了,影响是全局的。
  4. axios中以别名的形式(axios.get、axios.post)发请求,不同的请求方式参数的写法是不一样的,主要是put/post/patch三种方法与其他不太一样

自定义请求配置

根目录下新建plugins/axios/index.js文件,自定义axios的请求配置。

这里process.env.VUE_APP_BASEURL是一个定义好的变量,值为"/webapi";

设置超时时间timeout为10s。如下:

import axios from 'axios'

axios.defaults.baseURL = process.env.VUE_APP_BASEURL
axios.defaults.timeout = 10000
axios.defaults.headers['custom-defined-header-key'] = 'custom-defined-header-value'
// 自定义请求头:对所有请求方法生效
axios.defaults.headers.common['common-defined-key-b'] = 'custom value: for all methods'
// 自定义请求头:只对post方法生效
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// 自定义请求头:只对get方法生效
axios.defaults.headers.get['get-custom-key'] = 'custom value: only for get method';

export default axios

"main.js"文件:

import request from '@/plugins/axios/index.js'

Vue.prototype.$request = request

这样在组件内就可以通过this.$request(options)或者this.$request.get(options)的方法来请求数据了。

对常见的响应情况统一处理

这里主要是在"响应拦截器"中,对于一些常见的请求状态码和跟后端约定好的请求返回码做统一的前置处理。

新建axios.handleResponse.js文件,用于处理常见的正常响应:

# axios.handleResponse.js
// 处理响应错误码
export default (response) => {
   
    const status = response.status
    // 如果http响应状态码response.status正常,则直接返回数据
    if ((status >= 200 && status <= 300) || status === 304) {
   
        return response
    }
    // status不正常的话,根据与后端约定好的code,做出对应的提示与处理
    // 返回一个带有code和message属性的对象
    else {
   
        const code = parseInt(response.data && response.data.code)
        // msg为服务端返回的错误信息,字段名自定义,此处以msg为例
        let message = (response.data || {
   }).msg

        switch (code) {
   
            case 400:
                break
            case 4001:
                if (process.server) return
                message = message || '登录设备数量超出限制'
                // store.commit('savehttpResult', { res: response.data })
                break
            case 403:
                message = message || '未登录'
                break
            case 404:
                message = message || '请求地址错误'
                break
            case 412:
                message = message || '未找到有效session'
                break
            default:
                // message = message || err.response.data.msg
                break
        }
        return {
   
            code,
            message
        }
    }
}

新建plugins/axios/axios.handleError.js文件,用于处理常见的异常响应:

#plugins/axios/axios.handleError.js文件
export default (err) => {
   
    const {
    response } = err

    if (!response.status) {
   
        err.code = ''
        err.message = '有response但没有response.status的情况'
    }
    err.code = response.status
    switch (response.status) {
   
        case 200:
            err.message = '错误响应也会有状态码为200的情况'
            break
        case 400:
            err.message = '请求错误(400)'
            break
        case 401:
            err.message = '未授权,请重新登录(401)'
            break
        case 403:
            err.message = '拒绝访问(403)'
            break
        case 404:
            err.message = '请求出错(404)'
            break
        case 408:
            err.message = '请求超时(408)'
            break
        case 500:
            err.message = '服务器错误(500)'
            break
        case 501:
            err.message = '服务未实现(501)'
            break
        case 502:
            err.message = '网络错误(502)'
            break
        case 503:
            err.message = '服务不可用(503)'
            break
        case 504:
            err.message = '网络超时(504)'
            break
        case 505:
            err.message = 'HTTP版本不受支持(505)'
            break
        default:
            err.message = `连接出错,状态码:(${
     err.response.status})!`
    }
    return err
}

plugins/axios/index.js文件中引入并在拦截器中配置:

  • 如果请求被取消,会进入到响应拦截器的第二个参数err处理中
#plugins/axios/index.js文件
import axios from 'axios'
import handleResponse from '@/plugins/axios/axios.handleResponse.js'
import handleError 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值