react-native-cross-fetch
v0.0.2
Published
轻量请求库:三端可用(RN iOS/Android + Web),fetch 优先,必要时自动降级 XHR。
Downloads
326
Readme
react-native-cross-fetch
一个轻量级、跨平台的 HTTP 请求库,专为 React Native (iOS/Android) 和 Web 环境设计。
它提供了一套统一的 API(与常见 HTTP 客户端一致),在支持 fetch 的环境中优先使用 fetch,在不支持的环境或特殊场景下自动降级为 XMLHttpRequest。
✨ 特性
- 三端统一:一套代码同时运行在 React Native (iOS/Android) 和 Web 浏览器中。
- 自动降级:优先使用
fetch,必要时(如旧环境或特定配置)自动切换到XMLHttpRequest。 - 拦截器支持:支持请求和响应拦截器,方便进行 token 注入、日志记录、统一错误处理等。
- 类型安全:完全使用 TypeScript 编写,提供优秀的类型推导和定义。
- 功能丰富:
- 支持
baseURL和params自动序列化。 - 支持
paramsSerializer自定义参数序列化。 - 支持
timeout超时设置。 - 支持
AbortSignal取消请求。 - 支持
CancelToken取消请求。 - 自动处理 JSON 请求体和响应体。
- 自动处理
FormData文件上传。 - 支持
application/x-www-form-urlencoded自动编码。 - 支持 Web 场景的 XSRF(仅标准浏览器环境)。
- 支持
fetchOptions透传到底层fetch。
- 支持
- 错误处理:统一的
CrossFetchError错误对象,包含标准化的错误码。
✅ 为什么选择这个库
如果你只需要「React Native + Web」场景的 HTTP 基础能力(并希望尽可能轻量),这个库的优势在于:
- 只做必需能力:保留拦截器、参数/请求体序列化、响应解析、取消/超时、统一错误与响应结构;不引入与 RN/Web 无关的重功能(比如进度、Node 专属能力等)。
- fetch 优先 + 自动降级 XHR:默认使用现代
fetch,在不兼容/受限时可自动或手动切换到XMLHttpRequest,业务侧保持同一套 API 与数据结构。 - 0 运行时依赖:减少依赖冲突与体积负担,适合对启动性能、包体、升级风险更敏感的 RN 项目。
- 迁移成本低:API 与常见 HTTP 客户端一致(
create/request/verbs/interceptors/defaults),响应/错误结构稳定,历史代码更容易迁移。 - 保留底层控制:通过
fetchOptions透传redirect/mode/cache/keepalive等底层选项(需要时才用)。
⚠️ 不适用场景
- 你强依赖上传/下载进度(
onUploadProgress/onDownloadProgress) - 你需要 Node.js 专属能力(如
http/httpsadapter、agent、代理、cookie jar 等) - 你想要开箱即用的重策略能力(如重试、缓存、请求队列等;可以用拦截器自行实现)
📦 安装
使用 npm:
npm install react-native-cross-fetch使用 yarn:
yarn add react-native-cross-fetch🚀 快速上手
基础请求
import crossFetch from 'react-native-cross-fetch';
// 发起 GET 请求
crossFetch.get('https://api.example.com/user?ID=12345')
.then(function (response) {
// 处理成功情况
console.log(response.data);
console.log(response.status);
})
.catch(function (error) {
// 处理错误情况
console.log(error);
});
// 发起 POST 请求
crossFetch.post('https://api.example.com/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});兼容双参数 request 写法
// request(url, config)
await crossFetch.request('https://api.example.com/user', { method: 'get' });📖 详细使用指南
1. 创建实例
建议为你的 API 创建一个单独的实例,配置基础路径和超时时间。
import crossFetch from 'react-native-cross-fetch';
const api = crossFetch.create({
baseURL: 'https://api.example.com/v1',
timeout: 10000, // 10秒超时
headers: { 'X-Custom-Header': 'foobar' }
});
// 使用实例发起请求
await api.get('/users');2. 拦截器 (Interceptors)
你可以拦截请求或响应,在它们被处理之前进行操作。
// 添加请求拦截器
api.interceptors.request.use((config) => {
// 在发送请求之前做些什么,例如添加 Token
const token = 'your-auth-token';
if (token) {
config.headers = {
...config.headers,
Authorization: `Bearer ${token}`
};
}
return config;
}, (error) => {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
api.interceptors.response.use((response) => {
// 对响应数据做点什么
return response;
}, (error) => {
// 对响应错误做点什么,例如统一处理 401
if (error.response && error.response.status === 401) {
console.log('未授权,请登录');
}
return Promise.reject(error);
});3. TypeScript 支持
你可以为请求指定返回数据的类型,以获得更好的类型提示。
interface User {
id: number;
name: string;
email: string;
}
// 这里的 res.data 将会被推导为 User 类型
const res = await api.get<User>('/user/1');
console.log(res.data.name);4. 错误处理
库提供了 isCrossFetchError 辅助函数来判断错误类型,并访问详细的错误信息。
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) {
// 请求已发出,服务器响应了状态码,但状态码超出了 2xx 范围
console.log('状态码:', error.response.status);
console.log('响应数据:', error.response.data);
}
} else {
console.log('非请求错误:', error);
}
}5. 取消请求
支持使用 AbortController 来取消请求。
const controller = new AbortController();
api.get('/long-request', {
signal: controller.signal
}).catch(err => {
if (isCrossFetchError(err) && err.code === 'ERR_CANCELED') {
console.log('请求被取消');
}
});
// 取消请求
controller.abort();也支持 CancelToken:
const { token, cancel } = crossFetch.CancelToken.source();
const p = api.get('/long-request', { cancelToken: token });
cancel('stop');
await p;6. 文件上传 (FormData)
直接传入 FormData 对象即可,库会自动处理 Content-Type(自动删除 Content-Type 头以允许浏览器/原生层自动生成 boundary)。
const formData = new FormData();
formData.append('file', fileObject);
formData.append('userId', '123');
await api.post('/upload', formData, {
headers: {
// 注意:通常不需要手动设置 'Content-Type': 'multipart/form-data'
// 库会自动处理
}
});📦 响应结构 (Response)
返回结构如下(headers / config.headers 为 CrossFetchHeaders):
{
data,
status,
statusText,
headers,
config,
request // fetch: Request(若环境支持);xhr: XMLHttpRequest
}⚙️ 请求配置 (Request Config)
以下是可用的配置选项:
{
// URL 是必须的
url: '/user',
// 请求方法 (默认: 'get')
method: 'get', // 'get' | 'post' | 'put' | 'delete' | ...
// 基础 URL,会自动拼接到 url 前面
baseURL: 'https://some-domain.com/api/',
// 请求头
headers: { 'X-Requested-With': 'XMLHttpRequest' },
// URL 查询参数
// 必须是一个纯对象或 URLSearchParams 对象
params: {
ID: 12345
},
// 自定义 params 序列化
paramsSerializer: {
serialize(params) { /* ... */ }
},
// 请求体数据
// 仅适用于 'PUT', 'POST', 'DELETE', 'PATCH' 方法
// 可以是 string, plain object, ArrayBuffer, Blob, FormData 等
data: {
firstName: 'Fred'
},
// 请求超时时间(毫秒),默认 0(无超时)
timeout: 1000,
// 强制指定适配器 (可选 'fetch' | 'xhr')
// 默认会自动检测环境
adapter: 'fetch',
// 响应类型 (默认: 'json')
// 选项: 'arrayBuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json',
// 允许跨域携带凭证 (cookies)
withCredentials: false,
// 仅标准浏览器环境:XSRF
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
withXSRFToken: undefined,
// fetch 底层参数透传(如 redirect/mode/cache/keepalive 等)
fetchOptions: {},
// 取消
signal: new AbortController().signal,
cancelToken: crossFetch.CancelToken.source().token,
// 自定义状态码校验(返回 false 会抛错)
validateStatus(status) { return status >= 200 && status < 300; }
}📝 License
ISC
