【转载】vue3 Ts axios 封装

vue3 Ts axios 封装

安装 npm install axios --S

axios的封装

  • Axios默认使用application/json作为请求头的Content-Type,数据会自动转为UTF-8格式的JSON字符串‌。
  • 若需提交表单数据(如FormData),需显式设置Content-Type: multipart/form-data; charset=UTF-8
typescript 复制代码
import axios, { AxiosError, AxiosInstance, InternalAxiosRequestConfig, AxiosResponse, AxiosRequestConfig, AxiosHeaders } from 'axios'
import qs from 'qs'
import { config } from './config'
import { ElMessage } from 'element-plus'

// 从配置文件中提取相关配置
const { base_url, request_timeout, result_code } = config

// 创建 axios 实例
const service: AxiosInstance = axios.create({
  // 设置基础 URL,所有请求都会在这个地址基础上进行拼接
  baseURL: base_url,
  // 设置请求超时时间(单位:毫秒),超过这个时间还没响应则认为请求失败
  timeout: request_timeout,
  // 允许携带凭证(如 Cookie),用于处理跨域请求时需要传递 Cookie 的情况
  withCredentials: true,
  // 设置默认请求头,这里设置为 application/json,表示发送 JSON 格式的数据
  headers: { 'Content-Type': 'application/json' },
  // 自定义参数序列化函数,用于处理请求参数的序列化
  paramsSerializer: (params: any): string => {
    // 使用 qs 库进行参数序列化,并允许使用点号表示嵌套对象
    return qs.stringify(params, { allowDots: true })
  }
})

// request 拦截器,用于在请求发送前对请求进行处理
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig): InternalAxiosRequestConfig => {
    // 获取请求方法,并转换为大写
    const method = config.method?.toUpperCase()
    // 如果是 GET 请求
    if (method === 'GET') {
      // 设置请求头,防止 GET 请求缓存
      config.headers['Cache-Control'] = 'no-cache'
      config.headers['Pragma'] = 'no-cache'
    }
    // 如果是 POST 请求
    else if (method === 'POST') {
      // 获取请求头中的 Content-Type
      const contentType = config.headers['Content-Type'] || config.headers['content-type']
      // 如果 Content-Type 是 application/x-www-form-urlencoded
      if (contentType === 'application/x-www-form-urlencoded') {
        // 如果请求数据存在且不是字符串类型
        if (config.data && typeof config.data !== 'string') {
          // 使用 qs 库将请求数据序列化为 URL 编码格式的字符串
          config.data = qs.stringify(config.data)
        }
      }
    }
    // 返回处理后的配置,继续请求流程
    return config
  },
  (error: AxiosError): Promise<AxiosError> => {
    // 如果请求发生错误,返回错误的 Promise
    return Promise.reject(error)
  }
)

// response 拦截器,用于在接收到响应后对响应进行处理
service.interceptors.response.use(
  async (response: AxiosResponse<any>): Promise<any> => {
    // 获取响应数据
    let { data } = response
    // 如果响应数据不存在
    if (!data) {
      // 抛出错误,表示请求没有返回值
      throw new Error()
    }
    // 如果响应的 responseType 是 blob 或 arraybuffer(处理二进制数据,如文件下载)
    if (
      response.request.responseType === 'blob' ||
      response.request.responseType === 'arraybuffer'
    ) {
      // 如果响应的数据类型不是 application/json
      if (response.data.type !== 'application/json') {
        // 直接返回响应数据,进行文件下载等操作
        return response.data
      }
      // 如果响应的数据类型是 application/json,说明可能导出失败,将响应数据转换为 JSON 格式
      data = await new Response(response.data).json()
    }
    // 返回处理后的响应数据
    return data
  },
  (error: AxiosError): Promise<AxiosError> => {
    // 打印错误信息,用于调试
    console.log('err' + error)
    // 获取错误信息
    let { message } = error
    // 显示错误消息提示
    ElMessage.error(message)
    // 返回错误的 Promise,继续错误处理流程
    return Promise.reject(error)
  }
)

// 导出 axios 实例,供其他模块使用
export { service }

封装get post delete 方法

typescript 复制代码
import { service } from './service'
import { config } from './config'

const { default_headers } = config

// 定义请求方法的类型
type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' 

// 定义请求配置的类型
interface RequestOptions {
  method?: RequestMethod
  url?: string
  data?: any
  params?: any
  headers?: any
  responseType?: 'json' | 'blob' | 'arraybuffer'
  headersType?: string
  [key: string]: any
}

// 封装请求方法,用于统一处理请求配置
const request = (options: RequestOptions): Promise<AxiosResponse<any>> => {
  // 解构请求配置,提取 headersType 和 headers
  const { headersType, headers, ...otherOptions } = options
  // 使用 service 发起请求
  // 合并请求头,优先使用 headersType 或 default_headers,然后合并 headers
  return service({
    ...otherOptions,
    headers: {
      'Content-Type': headersType || default_headers, // 设置 Content-Type
      ...headers // 合并其他请求头
    }
  })
}

// 定义请求工具类,提供各种 HTTP 请求方法
export default {
  // GET 请求方法
  get: async <T = any>(option: RequestOptions): Promise<T> => {
    // 发起 GET 请求
    const res = await request({ method: 'GET', ...option })
    // 返回响应数据,并将其转换为指定类型
    return res.data as unknown as T
  },
  // POST 请求方法
  post: async <T = any>(option: RequestOptions): Promise<T> => {
    // 发起 POST 请求
    const res = await request({ method: 'POST', ...option })
    // 返回响应数据,并将其转换为指定类型
    return res.data as unknown as T
  },
  // 原始 POST 请求方法,返回完整的响应对象
  postOriginal: async (option: RequestOptions): Promise<AxiosResponse<any>> => {
    // 发起 POST 请求
    const res = await request({ method: 'POST', ...option })
    // 返回完整的响应对象
    return res
  },
  // DELETE 请求方法
  delete: async <T = any>(option: RequestOptions): Promise<T> => {
    // 发起 DELETE 请求
    const res = await request({ method: 'DELETE', ...option })
    // 返回响应数据,并将其转换为指定类型
    return res.data as unknown as T
  },
  // PUT 请求方法
  put: async <T = any>(option: RequestOptions): Promise<T> => {
    // 发起 PUT 请求
    const res = await request({ method: 'PUT', ...option })
    // 返回响应数据,并将其转换为指定类型
    return res.data as unknown as T
  },
  // 下载文件的请求方法
  download: async <T = any>(option: RequestOptions): Promise<T> => {
    // 发起 GET 请求,设置 responseType 为 blob,用于处理文件下载
    const res = await request({ method: 'GET', responseType: 'blob', ...option })
    // 返回响应数据,并将其转换为指定类型
    return res as unknown as Promise<T>
  },
  // 上传文件的请求方法
  upload: async <T = any>(option: RequestOptions): Promise<T> => {
    // 设置 headersType 为 multipart/form-data,用于文件上传
    option.headersType = 'multipart/form-data'
    // 发起 POST 请求
    const res = await request({ method: 'POST', ...option })
    // 返回响应数据,并将其转换为指定类型
    return res as unknown as Promise<T>
  }
}

config.ts部分

arduino 复制代码
/config.ts
type AxiosHeaders =
| 'application/json'
| 'application/x-www-form-urlencoded'
| 'multipart/form-data'

  const config: {
    base_url: string
    result_code: number | string
    default_headers: AxiosHeaders
    request_timeout: number
  } = {
    /**
     * api请求基础路径
     */
    base_url: import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL,
    /**
     * 接口成功返回状态码
     */
    result_code: 200,
  
    /**
     * 接口请求超时时间
     */
    request_timeout: 30000,
  
    /**
     * 默认接口请求类型
     * 可选值:application/x-www-form-urlencoded multipart/form-data
     */
    default_headers: 'application/json'
  }
  
  export { config }

版权声明:本文为CSDN博主「会飞的鱼先生」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/qq_44136028...

相关推荐
恋猫de小郭24 分钟前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端