Skip to content

封装

示例

js
import axios from 'axios';
import router from "@/router";
import {useUserStore} from '@/pinia-stores/user'
import { Message } from '@arco-design/web-vue'


const instance = axios.create({
    baseURL: 'http://localhost:8000',
    timeout: 10000,
    // 返回true表示正常响应,false控制台会报错
    validateStatus: (status) => {
        // 状态码小于500的正常响应
        return status < 500
    }
});

instance.interceptors.request.use(
    (config) => {
        // 所有请求加上请求头
        const userStore = useUserStore()
        config.headers['Authorization'] = 'bearer ' + userStore.access_token
        return config
    },
    (error) => {
        return Promise.reject(error)
    }
);

// 最大重试几次
const MAX_RETRY = 1
// 延迟重试,失败后立即重试会增加服务器负担
const RETRY_DELAY = 300
// 添加响应拦截器
instance.interceptors.response.use(
    async (response) => {
        const userStore = useUserStore()
        const { status, data = {} } = response

        if (status >= 400 && status < 500) {
            switch (status) {
                case 400:
                    // 登录页面已经有显示错误信息了,不用再显示
                    if (response.config.url !== '/login') {
                        Message.error(data.msg ?? '未知错误')
                    }
                    break
                case 401:
                    Message.error('请重新登录')
                    userStore.logout()
                    await router.replace({name: 'login'})
                    break
                case 403:
                    await router.push({name: '403Main'})
                    break
                // case 405: // 请求方法用错了,比如需要get请求,结果用的是post
            }
            throw new Error(data.msg ?? '未知错误')
        }
        return data
    },
    async (error) => {
        const { config, message, code, response } = error

        // 请求超时重试
        if (code === 'ECONNABORTED' && message?.startsWith('timeout') && config) {
            let { retryCount = 0 } = config
            if (retryCount < MAX_RETRY) {
                retryCount += 1
                config.retryCount = retryCount
                await new Promise((resolve) => setTimeout(() => resolve(), RETRY_DELAY))
                return await instance(config)
            }
        }

        // 500响应
        if (response) {
            const { data = {} } = response
            error.message = data?.msg ?? '服务器错误'
            await router.push({name: '500Main'})
        }
        throw error
    }
);

export default instance;