Skip to content

问下关于 axios 的一些问题 #5

@liuguangsen0409

Description

@liuguangsen0409

看了大佬对 axios 的封装,参照着封装后,我的类型是
image
但是看大佬的封装,request 是 any 类型
image

我在 api 层想通过泛型的方式去拿到返回值的具体类型,会报如下错误
image

完整代码如下

// request.ts
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
import axios from 'axios'
import qs from 'qs'
import cookie from 'js-cookie'
import storage from 'store2'
import { message } from '@/utils/message'
import { TOKEN, LOCALE_LANG, TENANT_ID } from '@/constants/store'
import { LOGIN_URL } from '@/constants/links'

// invalid token code
const FORBIDDEN_TOKEN_CODE = '40301'
// invalid auth
const FORBIDDEN_AUTH_CODE = '40302'
// success
const SUCCESS_CODE = '0'

const request = axios.create({
  baseURL: '/api',
  timeout: 30000,
  headers: {
    'X-Requested-With': 'XMLHttpRequest'
  }
})

const errorHandler = (error: any) => {
  if (error.response) {
    const { status, statusText } = error.response

    if (status === 403) {
      message('禁止的操作!')
    } else {
      message(statusText || 'HTTP 错误')
    }
    return Promise.reject(error.response)
  }

  return Promise.reject(error)
}

const queryParamsSerializer = (params: object) =>
  qs.stringify(params, { arrayFormat: 'comma' })

request.interceptors.request.use((config: AxiosRequestConfig) => {
  const token = cookie.get(TOKEN)
  const language = storage.get(LOCALE_LANG)
  const tenant = cookie.get(TENANT_ID)

  // if not login
  if (token) {
    config.headers!.fauthorization = token
  } else {
    // if have tenant redirect to login page
    if (tenant) {
      const url = encodeURIComponent(window.location.href)
      return window.location.href = `${LOGIN_URL}?url=${url}&tenant=${tenant}&systemSource=CLOUD_OA`
    } else { // not have tenant redirect to guide page
      return `${import.meta.env.VITE_APP_PROJECT_URL}/401`
    }
  }

  if (language) {
    config.headers!.language = language
  }

  config.paramsSerializer = queryParamsSerializer
  return config
}, errorHandler)

const needCompleteResponse = (response: AxiosResponse) => {
  const { responseType } = response.request
  return responseType === 'blob'
}

request.interceptors.response.use((response: AxiosResponse) => {
  if (needCompleteResponse(response)) {
    return response
  }

  const { data: httpData } = response
  const { code, data, message: msg } = httpData

  const codeStr = `${code}`

  switch(codeStr) {
    case SUCCESS_CODE:
      return data
    case FORBIDDEN_TOKEN_CODE: {
      const tenant = cookie.get('TENANT_ID')

      if (tenant) {
        const url = encodeURIComponent(window.location.href)
        return window.location.href = `${LOGIN_URL}?url=${url}&tenant=${tenant}&systemSource=CLOUD_OA`
      } else { // not have tenant redirect to guide page
        return `${import.meta.env.VITE_APP_PROJECT_URL}/401`
      }
    }
    case FORBIDDEN_AUTH_CODE:
      return `${import.meta.env.VITE_APP_PROJECT_URL}/401`
    default:
      message(msg || '业务错误')
      return Promise.reject(httpData)
  }
}, errorHandler)

export default request
// api.ts
import type { AxiosPromise } from 'axios'
import type { IRootObject } from '@/model/rootObject'
import type { IUser, ITenantItem, IMenuItem } from '@/model/userModel'
import request from '@/utils/request'

const BASE_URL = '/api'
export const api = {
  info: '/resources/user/info',
}

/**
 * get user basic info
 * @return {void} user basic info
 */
export const fetchUser = () =>
  request<IRootObject<IUser>>({
    baseURL: BASE_URL,
    url: api.info,
    method: 'post'
  })

谢谢大佬

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions