接口请求

项目中采用基于 axios 深度封装的 @uniboot/request 库处理所有 HTTP 请求。模板在 src/utils/request.ts 中通过 createHttpClient 创建业务客户端,并与 @uniboot/admin / @uniboot/auth 的账户相关客户端共用同一套鉴权与提示配置(由 src/setup/auth-runtime.tsbuildHttpCommonOptions 统一生成),保证改密、拉用户信息等接口也能自动携带 Token。

认证相关的桥接逻辑(HTTP 刷新回调、权限守卫、账户模块初始化)集中在 src/setup/auth-runtime.tssrc/utils/request.ts 仅负责创建各 HTTP 客户端实例。


客户端初始化

src/utils/request.ts 调用 buildHttpCommonOptions() 生成共享配置,再分别创建业务 request 与 admin/auth 专用客户端:

ts
import { createUnibootAdminHttpBundle } from '@uniboot/admin'
import { createHttpClient } from '@uniboot/request'

import configs from '@/config'
import { buildHttpCommonOptions } from '@/setup/auth-runtime'

export const httpCommonOptions = buildHttpCommonOptions()

const request = createHttpClient({
  baseURL: configs.proxy ? '/api' : configs.baseUrl,
  ...httpCommonOptions,
})

export const { adminApi, userApi, roleApi, authHttp, adminHttp } =
  createUnibootAdminHttpBundle({
    authServiceUrl: configs.authServiceUrl,
    adminServiceUrl: configs.adminServiceUrl,
    http: httpCommonOptions,
  })

export default request

公共请求头在 src/config/index.tsbuildHttpHeaders 中写死默认值(含 version 与业务侧租户头等);其他消费方若无此类需求,可在该函数内按需删减或修改,无需配置环境变量。

ts
// src/setup/auth-runtime.ts(节选)
export function buildHttpCommonOptions() {
  return {
    headers: config.httpHeaders,
    getToken,
    refreshToken: refreshHttpAccessToken, // 动态 import user store
    onRefreshTokenFail: onHttpRefreshTokenFail, // 调用 handleSessionExpired()
    // ...NProgress、i18n 提示等
  }
}

导出说明

导出项用途
request(默认导出)业务接口通用客户端(APP_PUBLIC_API_URL),src/api 中大部分自定义接口使用它。
httpCommonOptions与 admin/auth 客户端共享的超时、Token、提示、刷新等配置。
adminApi / adminHttp用户服务账号域 API / 底层 HTTP(改密、当前用户、验证码等),均走 APP_PUBLIC_ADMIN_SERVICE_URL
userApi / roleApi用户 / 角色管理域 API,固定绑定 adminHttp
authHttp授权服务底层 HTTP(APP_PUBLIC_AUTH_SERVICE_URL;登出、刷新 Token 等)。

初始化参数说明

createHttpClient 的完整选项类型为 CreateHttpClientOptions(定义于 @uniboot/request)。

配置项类型说明
baseURLstring接口基础地址。开启代理 configs.proxy 时用 /api,否则用 configs.baseUrl
timeoutnumber超时时间(毫秒),库内默认 60000
withCredentialsboolean是否跨域携带 Cookie;authMethodSESSION_COOKIE 时启用。
headersRecord<string, string>全局公共请求头;默认会合并 Content-Type: application/json
getToken() => string | null | undefined读取当前 access token,供拦截器写入鉴权头。
buildAuthHeader(token: string) => Record<string, string>自定义鉴权头格式,默认 Authorization: Bearer ${token}
onRequestStart / onRequestEnd() => void请求开始 / 结束钩子;模板中用于 NProgress
translate(msg: string) => string将后端 message / 内置文案键转为展示文案(如 i18n)。
msgSuccess / msgError(msg: string) => void成功 / 失败全局提示。
refreshToken() => Promise<string | null | undefined>收到 401 时刷新 access token;返回新 token,空值或抛错视为失败。
onRefreshTokenFail(error: unknown) => void刷新失败回调;模板中清空登录态并跳转登录页。
extraRequestHook(config) => config追加在默认请求拦截器之后,可改写单次请求配置。
overrideResponseHook / overrideErrorHook拦截器函数完全覆盖默认响应 / 错误拦截(一般不推荐)。
defaultRequestOptionsPartial<RequestOptions>见下一节。

默认请求选项 (defaultRequestOptions)

单次调用可通过第二个参数覆盖这些选项。

选项类型默认值说明
isParamsToDatabooleantruePOST 且未设置 data 时,自动把 params 挪到 data
isReturnDefaultResponsebooleanfalsetrue 时返回完整 Axios 响应(含 headersstatus),常用于 blob / 需读响应头的场景。
isTransformResponsebooleantruetrue 时按约定解包业务体;为 false 时直接返回 response.data
urlPrefixstringconfigs.urlPrefix拼在 baseURL 之后、业务 url 之前的前缀。
ignoreCancelTokenbooleanfalsefalse 时启用重复请求取消:相同请求未完成前再次发起会取消上一次。
withTokenbooleantrue是否自动携带 Token。刷新 Token、登录、验证码等接口应设为 false,避免 401 刷新递归。
errorTipbooleantrue失败时是否走 msgError 提示。
successTipbooleanfalse成功且响应带 message 时是否走 msgSuccess(增删改类接口可开)。
isOpenRetrybooleantrue是否在超时 / 断网时自动重试。
retryCountnumber2最大重试次数。

重试范围

自动重试仅针对 非 POST 请求,且错误码为 ECONNABORTED(超时)或 ERR_NETWORK(断网)。POST 不会自动重试,避免重复提交。


Token 自动刷新(401)

当配置了 refreshToken 时,错误拦截器在满足以下条件时会尝试刷新并重试原请求:

  1. HTTP 状态码为 401
  2. 该请求的 withToken !== false
  3. 该请求尚未因刷新而重试过(内部标记 _retryAfterRefresh

行为要点:

  • 并发合并:刷新进行中时,其它 401 请求会排队,共享同一次 refreshToken() 结果,避免并发重复刷新。
  • 成功:拿到新 access token 后,用原配置重发请求。
  • 失败:调用 onRefreshTokenFail,并 reject 原始错误。
  • 刷新接口自身:必须设置 withToken: false,否则可能再次触发刷新逻辑。

模板中 refreshToken 通过 refreshHttpAccessToken() 动态 import('@/stores/modules/user') 调用 refreshAccessToken();刷新接口与登录共用 authHttp(见 src/api/user.tsrefreshAccessToken),保证打到授权服务而非业务 API。

OAuth 换票成功后由权限守卫调用 userStore.setToken() 写入 access token;登出与刷新失败均调用 handleSessionExpired() 清空登录态。


响应解包与错误提示

默认响应拦截器(isTransformResponse: true)按 HTTP 状态处理:

成功(2xx)

  1. isReturnDefaultResponse,直接返回完整 AxiosResponse
  2. 否则从响应体中取业务数据:优先 result,其次 data,否则整份 data
  3. 若开启 successTip 且存在 message,调用 msgSuccess(translate(message))
  4. 返回解包后的业务数据。

失败(错误拦截器)

场景提示策略
请求被取消(ERR_CANCELED静默,不提示
401SESSION_TIMEOUT → 文案键 auth.loginTimeout;否则用服务端 message 或「未授权」
403「权限不足」
4xx优先拼接 detailsfield: message),否则用服务端 message
5xx「系统繁忙,请稍后重试」
超时 / 其它网络错误「请求超时…」或原始 error.message

errorTip: false 时可关闭上述气泡,由调用方自行处理。


接口调用示例

1. 标准业务 POST

ts
import request from '@/utils/request'

export function createOrder(data: CreateOrderParams) {
  return request.post<CreateOrderResult>({
    url: '/order/create',
    data,
  })
}

2. 覆盖提示与重试

ts
import request from '@/utils/request'

export function deleteUser(id: number) {
  return request.post(
    {
      url: '/user/delete',
      data: { id },
    },
    {
      successTip: true,
      isOpenRetry: false,
    }
  )
}

3. 使用 admin / auth 客户端

账户相关能力优先走 adminApi / authHttp(auth 模板登录为 OAuth,无 authApi.login):

ts
import { adminApi, authHttp } from '@/utils/request'

export function getUserInfo() {
  return adminApi.getCurrentUser()
}

export function logout() {
  return authHttp.get<unknown>({ url: '/oauth/logout' })
}

4. 验证码等特殊响应(blob / 不解包)

ts
import { adminHttp } from '@/utils/request'

export function captcha(params: Record<string, unknown>) {
  return adminHttp.get(
    { responseType: 'blob', url: '/captcha', params },
    {
      isReturnDefaultResponse: true,
      isTransformResponse: false,
      withToken: false,
    }
  )
}

5. 表单上传

ts
import request from '@/utils/request'

export function uploadAvatar(file: File) {
  const formData = new FormData()
  formData.append('file', file)

  return request.post({
    url: '/user/upload-avatar',
    data: formData,
    headers: {
      'Content-Type': 'multipart/form-data',
    },
  })
}

相关源码

路径说明
src/setup/auth-runtime.tsHTTP 共享配置、权限守卫、账户模块桥接
src/utils/request.ts模板侧客户端实例(httpCommonOptions、admin/auth 导出)
src/utils/auth-tokens.ts登录 / 刷新响应 token 解析(snake_case / camelCase 兼容)
src/utils/auth.tsclearAuthInfohandleSessionExpired
@uniboot/requestcreateHttpClient.ts拦截器、401 刷新排队、响应解包与错误提示
@uniboot/requestaxios.ts方法封装、重复请求取消、超时/断网重试
@uniboot/requesttypes.tsRequestOptions / RequestData 类型定义