HTTP 客户端
介绍
HTTPClient 是 @cat-kit/http 的核心入口。它负责:
- 组合
origin + prefix + url + query - 合并全局与单次请求配置
- 驱动插件链与引擎层
- 暴露
get/post/put/delete/patch/head/options等便捷方法
默认情况下,如果当前环境存在全局 fetch,会自动使用 FetchEngine;否则退回到 XHREngine。
快速使用
ts
import { HTTPClient } from '@cat-kit/http'
const http = new HTTPClient('/api', {
origin: 'https://example.com',
timeout: 10_000,
headers: { 'X-App': 'cat-kit' }
})
const users = await http.get<{ id: number; name: string }[]>('/users', {
query: { page: 1 }
})
await http.post('/users', { name: 'Mimi' })API参考
创建实例
ts
new HTTPClient(prefix?: string, config?: ClientConfig)常用配置:
ts
interface ClientConfig {
origin?: string
timeout?: number
headers?: Record<string, string>
credentials?: boolean
plugins?: HTTPClientPlugin[]
engine?: HttpEngine
}prefix用于给当前 client 统一加路径前缀origin只会作用于相对 URL;如果传入完整 URL,会跳过originengine可替换底层发送实现,适合 mock、特殊运行时或自定义 transport
发送请求
ts
request<T = any>(url: string, config?: RequestConfig): Promise<HTTPResponse<T>>
get<T>(url: string, config?: AliasRequestConfig): Promise<HTTPResponse<T>>
post<T = any>(url: string, body?: RequestConfig['body'], config?: Omit<RequestConfig, 'method' | 'body'>): Promise<HTTPResponse<T>>
put<T = any>(url: string, body?: RequestConfig['body'], config?: Omit<RequestConfig, 'method' | 'body'>): Promise<HTTPResponse<T>>
delete<T = any>(url: string, config?: Omit<RequestConfig, 'method'>): Promise<HTTPResponse<T>>
patch<T = any>(url: string, body?: RequestConfig['body'], config?: Omit<RequestConfig, 'method' | 'body'>): Promise<HTTPResponse<T>>
head<T = any>(url: string, config?: Omit<RequestConfig, 'method'>): Promise<HTTPResponse<T>>
options<T = any>(url: string, config?: Omit<RequestConfig, 'method'>): Promise<HTTPResponse<T>>常用请求配置:
ts
interface RequestConfig {
method?: RequestMethod
body?: BodyInit | Record<string, any>
query?: Record<string, any>
headers?: Record<string, string>
timeout?: number
credentials?: boolean
responseType?: 'json' | 'text' | 'blob' | 'arraybuffer'
signal?: AbortSignal
onUploadProgress?: (info: ProgressInfo) => void
onDownloadProgress?: (info: ProgressInfo) => void
}几个关键行为:
- 对象类型
body会自动序列化成 JSON,并补Content-Type: application/json query会附加到 URL 上;数组会展开成重复 key,对象会JSON.stringifyonDownloadProgress在FetchEngine流式读取时可用onUploadProgress只有XHREngine会真正回调,FetchEngine下会被静默忽略
请求分组
ts
const api = new HTTPClient('/api')
const users = api.group('/users')
await users.get('/profile') // /api/users/profilegroup() 的语义:
- 子 client 继承父 client 的
origin、timeout、credentials、headers - 父子共享同一个
engine - 父插件会影响子插件链;子注册的插件不会反向影响父 client
运行时注册插件
ts
const http = new HTTPClient()
http.registerPlugin({
name: 'trace-id',
beforeRequest(url, config) {
return {
url,
config: {
...config,
headers: { ...config.headers, 'X-Trace-Id': crypto.randomUUID() }
}
}
}
})约束:
- 每个插件必须有非空
name - 同一条父子链里插件名必须唯一,冲突会抛
HTTPError({ code: 'PLUGIN' })
中止请求
ts
const http = new HTTPClient()
http.get('/slow')
http.abort()abort() 会调用当前 engine.abort(),因此在父子 group() 共享引擎时,任一侧调用 abort() 都会中止该引擎上的在途请求。
错误处理
请求失败时会抛 HTTPError:
ts
import { HTTPError } from '@cat-kit/http'
try {
await http.get('/users')
} catch (error) {
if (error instanceof HTTPError) {
console.log(error.code)
console.log(error.response?.code)
}
}常见 code:
TIMEOUTABORTEDNETWORKPARSERETRY_LIMIT_EXCEEDEDPLUGIN
自定义引擎
ts
import { HTTPClient, HttpEngine } from '@cat-kit/http'
import type { HTTPResponse, RequestConfig } from '@cat-kit/http'
class MockEngine extends HttpEngine {
async request<T = any>(_url: string, _config: RequestConfig): Promise<HTTPResponse<T>> {
return {
data: { ok: true } as T,
code: 200,
headers: {}
}
}
abort(): void {}
}
const http = new HTTPClient('', { engine: new MockEngine() })