Axios

128 阅读2分钟

为什么要封装axios?

前端发起请求都需要考虑以下几种情况:

  • 环境配置(本地环境、测试环境、生产环境...)
  • 通用请求头配置
  • 请求前参数处理
  • 请求后数据处理
  • 异常处理
  • 请求错误怎么办?重试操作
  • 出现重复请求怎么办?
  • 接口日志的收集
  • 等等哈...

开始操作

用到的包如下:

  • axios(请求主库)
  • axios-retry(axios附赠的重试库)
  • element-ui(第三方库的提示语方法)
  • qs(用来处理一些参数等,不用也可以,可以直接使用JSON.stringfy())
  • crypto-js(用来加密等)

前提:

  • 新建一个request.js文件来写封装的方法
  • 新建一个config.js来放Axios的配置参数

config.js配置:

// axios配置
export const axiosConfig = {
    baseURL_dev: 'http://127.0.0.1:9675',	// 测试环境地址
    baseURL_prod: '',		// 正式环境地址
    timeout: 3000,	// 超时时间(可以根据不同的环境配置响应时间)
    withCredentials: true, // 是否允许携带cookie
    retries: 0,	// 请求失败重试次数
    shouldResetTimeout: true,	// 重试的时候是否重置超时时间
    retryDelay: 0,	// 每个请求之间的重试延迟时间(ms)
}

request.js配置:

import axios from "axios";
import { axiosConfig } from './config'
import { Message } from 'element-ui';
import axiosRetry from 'axios-retry'

// 判断是否是生产环境
const isProd = () => process.env.NODE_ENV === 'production'
const {
    baseURL_dev,
    baseURL_prod,
    timeout,
    withCredentials,
    retries,
    shouldResetTimeout,
    retryDelay,
} = axiosConfig

// 创建axios实例
const axiosService = axios.create({
    baseURL: isProd() ? baseURL_prod : baseURL_dev,
    timeout,
    withCredentials,
})

// 重试操作
axiosRetry(axiosService, {
    retries,
    shouldResetTimeout,
    retryDelay: (retryCount) => retryCount * retryDelay,
    retryCondition: (error) => {
        // 包含超时,则返回错误
        return error.message.includes('timeout')
    },
})

// 配置通用请求头
const headers = {
    // getLocalLang()是获取项目语言的方法,想把语言给到服务端,然后服务端可以根据不同的语种返回数据
    // language: getLocalLang(),
    'Content-Type': 'application/json',
    // 主要用来处理项目的鉴权,假如我们使用了第三方存储库,例如pinia,redux等,如果想直接在此处获取配置,是有问题的,所以可以动态配置在请求拦截use中
    // Authorization: getToken(),
}
// 请求拦截
axiosService.interceptors.request.use(
    (config) => {
        config.headers = {
            // 自己配置的通用的headers
            ...headers,
            // 默认的headers(接口处传递的herders),传递的默认要覆盖默认的,所以放后面
            ...config.headers,
        }

        return config
    },
    // 错误处理
    (error) => errorHandler(error)
)

// 响应拦截
axiosService.interceptors.response.use(
    (response) => {
        const { config, data } = response

        // 错误处理(我们的所有接口都会默认返回一个success用来判断成功还是失败)
        if (data && !data.success) {
            return errorHandler(data)
        }

        // do something.....

        return data
    },
    // 错误处理
    (error) => errorHandler(error)
)

// 错误处理
const errorHandler = (error) => {
    Message.error('请求异常,请稍后重试!')
    return Promise.reject(error) // null
}

// 默认导出
export default axiosService