npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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 编写,提供优秀的类型推导和定义。
  • 功能丰富
    • 支持 baseURLparams 自动序列化。
    • 支持 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/https adapter、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.headersCrossFetchHeaders):

{
  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