轻量请求库:三端可用(RN iOS/Android + Web),fetch 优先,必要时自动降级 XHR。
一个极致精简、高性能的跨平台 HTTP 请求库,专为 React Native (iOS/Android) 和 Web 环境设计。
单文件 ~1700 行 TypeScript,ESM 46KB / gzip 12KB,零运行时依赖。
它提供了一套统一的 API(与主流 HTTP 客户端一致),在支持 fetch 的环境中优先使用 fetch,在不支持的环境或特殊场景下自动降级为 XMLHttpRequest。
| 库 | min 体积 | gzip 体积 | 运行时依赖 |
|----|----------|-----------|------------|
| react-native-cross-fetch | 46 KB | ~12 KB | 0 |
| axios | ~55 KB | ~14 KB | 0(但含 Node 适配器) |
| ky | ~22 KB | ~8 KB | 0(仅 fetch,无 XHR 降级) |
> 与 axios 功能覆盖度接近(拦截器、取消、超时、FormData、参数序列化),但不含 Node.js 专属代码,体积更小,且针对 RN + Web 场景做了专项优化。
- 三端统一:一套代码同时运行在 React Native (iOS/Android) 和 Web 浏览器中
- 极致精简:单文件实现,零运行时依赖,gzip 后仅 ~12KB
- fetch 优先 + 自动降级 XHR:默认使用现代 fetch,必要时自动切换到 XMLHttpRequest
- 完整的类型安全:100% TypeScript 编写,提供完整的 .d.ts 类型定义
- 高性能设计:
- 拦截器链路优化,减少不必要的 Promise 创建
- XHR 适配器自动将 header 转为 Title-Case 避免兼容性问题
- 请求/响应 transformer 延迟求值,零开销默认路径
- 功能丰富:
- 拦截器(请求/响应),支持同步与异步模式
- baseURL + params 自动拼接与序列化
- paramsSerializer 自定义参数序列化
- timeout 超时设置
- AbortSignal / CancelToken 双重取消机制
- 自动处理 JSON 请求体和响应体
- 自动处理 FormData 文件上传
- application/x-www-form-urlencoded 自动编码
- Web XSRF 防护(仅标准浏览器环境)
- fetchOptions 透传到底层 fetch
- parseReviver 自定义 JSON 解析
- HttpStatusCode 双向状态码映射
- 统一错误处理:CrossFetchError 带标准化错误码(ERR_NETWORK / ERR_CANCELED / ECONNABORTED 等)
| 需求 | react-native-cross-fetch | axios | ky |
|------|--------------------------|-------|----|
| RN iOS/Android + Web 三端统一 | ✅ | ⚠️ 含 Node 冗余代码 | ⚠️ 仅 fetch |
| fetch 优先 + XHR 降级 | ✅ | ✅ | ❌ 仅 fetch |
| 拦截器 | ✅ | ✅ | ✅ hooks |
| 取消请求 (AbortSignal + CancelToken) | ✅ | ✅ | ✅ 仅 AbortSignal |
| 零运行时依赖 | ✅ | ✅ | ✅ |
| gzip < 15KB | ✅ ~12KB | ❌ ~14KB | ✅ ~8KB |
| 完整 TypeScript 类型 | ✅ | ✅ | ✅ |
核心优势:
- 只做必需能力:保留拦截器、参数/请求体序列化、响应解析、取消/超时、统一错误与响应结构;不引入与 RN/Web 无关的重功能
- 0 运行时依赖:减少依赖冲突与体积负担,适合对启动性能、包体、升级风险更敏感的 RN 项目
- 迁移成本低:API 与 axios 一致(create/request/get/post/interceptors/defaults),轻松迁移
- 你强依赖上传/下载进度(onUploadProgress / onDownloadProgress)
- 你需要 Node.js 专属能力(如 http/https adapter、agent、代理、cookie jar 等)
- 你想要开箱即用的重策略能力(如重试、缓存、请求队列等;可以用拦截器自行实现)
``bash`
npm install react-native-cross-fetch
`bash`
yarn add react-native-cross-fetch
`typescript
import crossFetch from 'react-native-cross-fetch';
// GET
const res = await crossFetch.get('https://api.example.com/user', {
params: { id: 12345 }
});
console.log(res.data);
// POST
await crossFetch.post('https://api.example.com/user', {
firstName: 'Fred',
lastName: 'Flintstone'
});
`
`typescript
const api = crossFetch.create({
baseURL: 'https://api.example.com/v1',
timeout: 10000,
headers: { 'X-Custom-Header': 'foobar' }
});
await api.get('/users');
`
`ts`
await crossFetch.request('https://api.example.com/user', { method: 'get' });
`typescriptBearer ${getToken()}
// 请求拦截器 — 注入 Token
api.interceptors.request.use((config) => {
config.headers = {
...config.headers,
Authorization:
};
return config;
});
// 响应拦截器 — 统一处理 401
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
console.log('未授权,请登录');
}
return Promise.reject(error);
}
);
`
`typescript
interface User {
id: number;
name: string;
email: string;
}
const res = await api.get
console.log(res.data.name); // 类型安全
`
`typescript
import { isCrossFetchError } from 'react-native-cross-fetch';
try {
await api.get('/user/12345');
} catch (error) {
if (isCrossFetchError(error)) {
if (error.code === 'ECONNABORTED') console.log('请求超时');
else if (error.code === 'ERR_NETWORK') console.log('网络错误');
else if (error.response) {
console.log('状态码:', error.response.status);
console.log('响应数据:', error.response.data);
}
}
}
`
`typescript
// 方式一:AbortController(推荐)
const controller = new AbortController();
api.get('/data', { signal: controller.signal });
controller.abort();
// 方式二:CancelToken
const { token, cancel } = crossFetch.CancelToken.source();
api.get('/data', { cancelToken: token });
cancel('不再需要');
`
`typescript
const formData = new FormData();
formData.append('file', fileObject);
formData.append('userId', '123');
// Content-Type 会自动处理,无需手动设置
await api.post('/upload', formData);
`
`ts`
{
data, // 响应数据(自动 JSON 解析)
status, // HTTP 状态码
statusText, // 状态文本
headers, // CrossFetchHeaders 实例
config, // 请求配置
request // fetch: Request | xhr: XMLHttpRequest
}
`typescript`
{
url: '/user', // 请求路径(必填)
method: 'get', // 请求方法,默认 'get'
baseURL: 'https://api.example.com/', // 基础 URL,自动拼接
headers: {}, // 请求头
params: { ID: 12345 }, // URL 查询参数
paramsSerializer: { serialize(p) {} }, // 自定义参数序列化
data: { key: 'value' }, // 请求体(POST/PUT/PATCH/DELETE)
timeout: 10000, // 超时时间(ms),默认 0(无超时)
adapter: 'fetch', // 强制指定适配器:'fetch' | 'xhr'
responseType: 'json', // 响应类型:json | text | blob | arraybuffer | stream | formdata
withCredentials: false, // 跨域携带凭证
signal: controller.signal, // AbortSignal 取消
cancelToken: token, // CancelToken 取消
validateStatus: (s) => s < 400, // 自定义状态码校验
fetchOptions: {}, // 透传到底层 fetch(redirect/mode/cache 等)
transitional: { // 过渡选项
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false,
},
parseReviver: (key, val) => val, // JSON.parse reviver
env: { fetch, XMLHttpRequest }, // 自定义环境注入
}
`typescript``
import crossFetch, {
CrossFetchError,
CrossFetchHeaders,
CanceledError,
CancelToken,
isCrossFetchError,
isCancel,
mergeConfig,
getAdapter,
toFormData,
formToJSON,
HttpStatusCode,
VERSION,
all,
spread,
} from 'react-native-cross-fetch';
ISC