关于 http-clients
http-clients 是面向 TypeScript 开发者的 HTTP 客户端参考 Skill,涵盖 Axios、Fetch API、ky 和 ofetch 的配置模式,并提供生产检查清单与故障排查建议。
主要功能
- 01Axios 配置示例
- 02Fetch API 封装模式
- 03ky 和 ofetch 配置
- 04HTTP 客户端反模式
- 05生产检查清单与故障排查
适用场景
- 01配置 TypeScript HTTP 客户端
- 02选择文档中的客户端模式
- 03检查 API 客户端的生产准备情况
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill http-clients安装后在 Claude Code 中输入/http-clients确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
advanced.mdquick-ref/axios.mderror-handling.mdfetch.mdinterceptors.mdky-ofetch.md详细介绍
HTTP 客户端核心知识
完整参考:有关令牌刷新流程、带指数退避的重试、请求取消和类型安全的 API 客户端模式,请参阅 advanced.md。
深入了解:使用
mcp__documentation__fetch_docs,并将 technology 设为:http-clients,以获取完整文档。
Axios 设置
import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios';
const api = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
timeout: 10000,
headers: { 'Content-Type': 'application/json' },
});
// Request interceptor - add auth token
api.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const token = localStorage.getItem('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response interceptor - handle errors
api.interceptors.response.use(
(response) => response,
(error: AxiosError) => {
if (error.response?.status === 401) {
window.location.href = '/login';
}
return Promise.reject(error);
}
);
Fetch API 封装
class ApiError extends Error {
constructor(public status: number, public statusText: string, public data?: unknown) {
super(`${status}: ${statusText}`);
}
}
async function fetchWithTimeout(url: string, options: RequestInit & { timeout?: number } = {}): Promise<Response> {
const { timeout = 10000, ...fetchOptions } = options;
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
return await fetch(url, { ...fetchOptions, signal: controller.signal });
} finally {
clearTimeout(timeoutId);
}
}
export async function apiFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
const token = localStorage.getItem('accessToken');
const headers: HeadersInit = {
'Content-Type': 'application/json',
...(token && { Authorization: `Bearer ${token}` }),
};
const response = await fetchWithTimeout(`${API_URL}${endpoint}`, { ...options, headers });
if (!response.ok) {
throw new ApiError(response.status, response.statusText);
}
return response.json();
}
ky(现代 Fetch 封装)
import ky from 'ky';
const api = ky.create({
prefixUrl: process.env.NEXT_PUBLIC_API_URL,
timeout: 10000,
retry: {
limit: 2,
methods: ['get', 'put', 'delete'],
statusCodes: [408, 429, 500, 502, 503, 504],
},
hooks: {
beforeRequest: [
(request) => {
const token = localStorage.getItem('accessToken');
if (token) {
request.headers.set('Authorization', `Bearer ${token}`);
}
},
],
},
});
// Usage
const users = await api.get('users').json<User[]>();
const user = await api.post('users', { json: newUser }).json<User>();
ofetch(通用 Fetch)
import { ofetch } from 'ofetch';
const api = ofetch.create({
baseURL: process.env.NUXT_PUBLIC_API_URL,
retry: 2,
retryDelay: 500,
timeout: 10000,
async onRequest({ options }) {
const token = localStorage.getItem('accessToken');
if (token) {
options.headers = { ...options.headers, Authorization: `Bearer ${token}` };
}
},
});
// Works in Node.js and browser
const users = await api<User[]>('/users');
何时不应使用此技能
- Axios 专属配置(使用
axios技能) - GraphQL 客户端设置(使用
graphql-codegen技能) - tRPC 客户端配置(使用
trpc技能) - WebSocket 或服务器发送事件
反模式
| 反模式 | 问题所在 | 解决方案 |
|---|---|---|
| 未配置超时 | 请求会一直挂起 | 为所有客户端设置超时 |
| API URL 硬编码 | 与环境耦合 | 使用环境变量 |
| 未配置重试逻辑 | 临时故障会导致用户体验不佳 | 实现指数退避 |
| 忽略令牌过期 | 出现 401 错误 | 实现令牌刷新流程 |
| 卸载时未取消请求 | 内存泄漏 | 使用 AbortController 清理 |
| 响应未指定类型 | 运行时错误 | 使用 TypeScript 泛型 |
快速故障排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| CORS 错误 | 服务端配置错误 | 在后端配置 CORS |
| 过一段时间后出现 401 | 令牌已过期 | 实现令牌刷新 |
| 内存泄漏 | 卸载时未中止请求 | 在 useEffect 中添加清理逻辑 |
| 网络超时 | 服务端响应缓慢 | 延长超时时间并添加重试 |
| 无限刷新循环 | 刷新请求返回 401 | 将刷新请求排除在拦截器之外 |
生产环境检查清单
- 通过环境变量设置基础 URL
- 已配置请求超时
- 已配置身份验证令牌拦截器
- 已配置令牌刷新逻辑
- 已配置错误响应处理
- 已配置带指数退避的重试
- 卸载时取消请求
- API 方法类型安全
参考文档
评论
支持 Markdown