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来解决
具体修改方法为:
- 打开
android/app/src/main/AndroidManifest.xml - 找到
<application标签 - 添加
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 来生成