axios二次封装

E和弦的根音 · 2021-03-16 · 1915 次浏览

/**axios封装
 * 请求拦截、相应拦截、错误统一处理
 */
import axios from 'axios'
// import QS from 'qs';
import {
    message,
    getStore
} from '@/config/utils'
import router from '@/router'
import store from '@/store'

let baseURL =
    process.env.NODE_ENV === 'development' ?
    'api' :
    process.env.VUE_APP_BASE_URL

let reqList = []

/**
 * 阻止重复请求
 * @param {array} reqList - 请求缓存列表
 * @param {string} url - 当前请求地址
 * @param {function} cancel - 请求中断函数
 * @param {string} errorMessage - 请求中断时需要显示的错误信息
 */
const stopRepeatRequest = function (reqList, url, cancel, errorMessage) {
    const errorMsg = errorMessage || ''
    for (let i = 0; i < reqList.length; i++) {
        if (reqList[i] === url) {
            cancel(errorMsg)
            return
        }
    }
    reqList.push(url)
}

/**
 * 允许某个请求可以继续进行
 * @param {array} reqList 全部请求列表
 * @param {string} url 请求地址
 */
const allowRequest = function (reqList, url) {
    for (let i = 0; i < reqList.length; i++) {
        if (reqList[i] === url) {
            reqList.splice(i, 1)
            break
        }
    }
}


const instance = axios.create({
    baseURL,
    timeout: 10000
})

// post请求头
instance.defaults.headers.post['Content-Type'] =
    'application/x-www-form-urlencoded;charset=UTF-8'

// 请求拦截器
instance.interceptors.request.use(
    config => {
        let cancel
        // 设置cancelToken对象
        config.cancelToken = new axios.CancelToken(function (c) {
            cancel = c
        })
        // 阻止重复请求。当上个请求未完成时,相同的请求不会进行
        stopRepeatRequest(reqList, config.url, cancel, `${config.url} 请求被中断`)
        const token = getStore('token')
        token && (config.headers.token = token)
        return config
    },
    error => {
        return Promise.error(error)
    }
)

// 响应拦截器
instance.interceptors.response.use(
    response => {

        setTimeout(() => {
            allowRequest(reqList, response.config.url)
        }, 1000)

        if (response.data.code === 1) { // 这里根据自家业务自行判断
            return response.data.data
        } else {
            handleCode(response.data)
            return Promise.reject(response.data)
        }
    },
    // 处理请求错误码
    error => {
        if (axios.isCancel(error)) {
            console.log(error.message)
        } else {
            // 增加延迟,相同请求不得在短时间内重复发送
            setTimeout(() => {
                allowRequest(reqList, error.config.url)
            }, 1000)
        }
        handleCode({code: error.response.status})
    return Promise.reject(error.response)
    }
)

// 处理后台错误码
function handleCode(data) {
    switch (data.code) {
        case 0:
            message.error(data.message || '网络错误')
            break
        case 401:
            store.commit('loginOut')
            router.replace({
                path: '/login',
                query: {
                    redirect: router.currentRoute.fullPath
                }
            })
            break
        case 403:
            store.commit('loginOut')
            router.replace({
                path: '/login',
                query: {
                    redirect: router.currentRoute.fullPath
                }
            })
            break

        default:
            break
    }
}

/**
 * get方法,对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function get(url, params) {
    return instance.get(url, {
        params: params
    })
}

/**
 * post方法,对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function post(url, params) {
    return instance.post(url, params)
}

/**
 * delete方法,对应delete请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function del(url, params) {
    return instance.delete(url, {
        params: params
    })
}

/**
 * put方法,对应put请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function put(url, params) {
    return instance.put(url, params)
}
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎评论,对作者也是一种鼓励。
查看评论 - 0 条评论