@ixook/request
v1.0.3
Published
Axios 请求客户端。默认按「HTTP 200 + `{ code, data, message }` 信封」解包;token、未授权之后的行为和 Toast 由调用方注入。不提供单例,不放业务 API。
Readme
@ixook/request
Axios 请求客户端。默认按「HTTP 200 + { code, data, message } 信封」解包;token、未授权之后的行为和 Toast 由调用方注入。不提供单例,不放业务 API。
安装
pnpm add @ixook/request快速使用
import { createRequest, isCanceled } from '@ixook/request'
const http = createRequest({
baseURL: import.meta.env.VITE_API_DOMAIN + import.meta.env.VITE_API_PREFIX,
timeout: 60_000,
getToken: () => localStorage.getItem('token') ?? undefined,
onUnauthorized: () => {
// 信封 code 401 或网关 HTTP 401:logout / 跳转登录
},
onError: (error) => {
if (isCanceled(error)) {
return
}
// Toast 等,由业务决定
},
})
const { data, total } = await http.get<Book[]>('/books', {
params: { page: 1 },
})
http.cancelAll()省略 envelope 时等价于 { successCode: 200, unauthorizedCode: 401, pick: 'envelope' },get<T>() 的 T 是内层 payload,返回值为 { data, code, message, total? }。默认信封下 HTTP 2xx 但 body 没有数字 code 会失败(kind: 'unknown')。对接 httpbin、对象存储等无信封的接口时传 envelope: false,此时 get<T>() 返回 HTTP body。
多个域名
每个 origin 一个客户端。钩子只配一次,用 extend 换 baseURL:
const api = createRequest({
baseURL: import.meta.env.VITE_API_DOMAIN + import.meta.env.VITE_API_PREFIX,
getToken: () => userStore.token,
onUnauthorized: () => userStore.logout(),
onError,
})
const upload = api.extend({
baseURL: import.meta.env.VITE_UPLOAD_DOMAIN,
timeout: 120_000,
})
const maps = api.extend({
baseURL: 'https://maps.example.com',
getToken: undefined,
envelope: false,
})upload.cancelAll() 不会取消 api 上的请求。偶发打到另一个 origin 也可单次覆盖:api.get('/legacy', { baseURL: 'https://old-api.example.com' })。
取消请求
使用 AbortController,不提供已废弃的 CancelToken。
await http.get('/search', { params: { q }, requestKey: 'search' })
http.cancel('search')
http.cancelAll()
const controller = new AbortController()
await http.get('/slow', { signal: controller.signal })
controller.abort()相同 requestKey 的新请求会 abort 旧请求。取消错误不调用 onError。
API
createRequest(options) 默认返回 EnvelopeClient;envelope: false 或 pick: 'data' 时返回 RequestClient。方法:request / get / post / put / patch / delete / cancel / cancelAll / extend。axios 为逃逸口。
| 选项 | 说明 |
| ------------------- | ------------------------------------------------------------------------------------ |
| baseURL | 必填 |
| timeout | 透传 Axios |
| getToken | 可选。返回值写成 Authorization: Bearer ... |
| onUnauthorized | 信封 unauthorizedCode(默认 401)或网关 HTTP 401。不调用 onError |
| onError | 业务码失败与传输层错误(404 / 超时 / 网络)。取消除外 |
| envelope | 默认开启。false 时返回 HTTP body。可配 successCode / unauthorizedCode / pick |
| transformResponse | 若传入则覆盖信封解包 |
单次请求可设 requestKey、skipAuth、skipErrorHandler、signal、baseURL、envelope: false。envelope: false 时该方法返回裸 body(类型为 T)。responseType 为 blob 或 arraybuffer 时运行时也跳过信封,但类型仍是信封;要类型正确请用 envelope: false。client.axios 逃逸口的取消只认调用方自己的 signal,不进 cancelAll。
错误分类:isCanceled(error)(含 axios.isCancel、ERR_CANCELED、CanceledError)、getRequestErrorKind(error)(canceled / timeout / network / http / unauthorized / biz / unknown)。不实现 refresh 队列。信封码默认 200 / 401,可配;logout 与 Toast 仍由调用方注入。
版本要求
- TypeScript 5.8+
- 依赖
axios
