React Native —— 3. 网络请求

771 阅读2分钟

React Native 网络请求

React Native 提供了和 web 标准一致的Fetch API以及内置了XMLHttpRequest API(也就是俗称的 ajax)。一些基于 XMLHttpRequest 封装的第三方库也可以使用,例如frisbee或是axios等。

由于以前写的项目都是使用的 axios,所以这里我继续选用 axios,还是跟之前一样在使用之前做一些封装,把请求和响应拦截器处理一下,比较重要的是最后面的 apk 无法访问 http 请求的问题。

安装依赖

安装 axios 和持久化存储库 async-storage

yarn add axios
npx expo install @react-native-async-storage/async-storage

Axios 封装

新增 /constants/index.ts,增加以下代码

export const domain = "https://xxxx.com";

新增 /request/index.ts,增加以下代码,按自己项目修改

import axios from "axios";
import { domain } from "../constants";
import AsyncStorage from "@react-native-async-storage/async-storage";

const request = axios.create({
  baseURL: `${domain}/api`,
  // 这里处理 axios 将哪些 HTTP 状态码视为 resolve 或 reject
  // 如果返回 true、null、undefined,promise将会resolve;其他情况则会被 reject
  // 默认为 validateStatus: (status) => status >= 200 && status < 300
  validateStatus: () => true,
});

request.interceptors.request.use(
  async (config) => {
    // 携带 token
    // 这里请求拦截器可按自己需求修改
    const token = (await AsyncStorage.getItem("token")) || "";

    config.headers["Authorization"] = token;
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

request.interceptors.response.use(
  async (response) => {
    if (response.status === 200) {
      return response.data;
    } else {
      // 401 清除 token 信息
      // 这里响应拦截器可按自己需求修改
      if (response.status === 401) {
        await AsyncStorage.removeItem("token");
        return Promise.reject(response);
      }
      return Promise.reject(response);
    }
  },
  (error) => {
    return Promise.reject(error);
  }
);

export default request;

API 封装

为了统一管理接口请求地址,新增 /request/api文件夹,将 api 按模块存放,比如 user 模块就在文件夹中新增 user.ts

import request from "..";

export const login = (data: any) => {
  return request('/login', {
    method: 'POST',
    data
  });
};

安卓请求 http 失败

需要注意的是如果出现使用安卓模拟器或者真机调试时可以访问 http 请求,但是打包成APK无法访问这种情况,需要通过修改 AndroidManifest.xml来解决

具体修改方法为:

  1. 打开 android/app/src/main/AndroidManifest.xml
  2. 找到 <application 标签
  3. 添加 android:usesCleartextTraffic="true"

修改完成后如下

<application
    android:name=".MainApplication"
    android:label="@string/app_name"
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:allowBackup="true"
    android:theme="@style/AppTheme"
    android:usesCleartextTraffic="true"
>
  ...
</application>

如果是通过 expo 创建的项目,没有 android目录,则可以通过 npx expo prebuild 来生成