一、引言
在 Harmony OS NEXT / 5.0 / API 12+ 版本的应用开发中,网络请求是非常关键的部分。Axios 作为一款流行的 HTTP 客户端库,能够帮助开发者轻松地处理网络请求。本文将详细介绍如何在 Harmony OS 项目中下载、导入并封装 Axios,以及在使用过程中的一些常见问题及解决方法。
二、适用版本说明
本文内容基于 Harmony OS NEXT / 5.0 / API 12+ 版本,该版本提供了良好的开发环境和 API 支持,使得 Axios 在项目中的集成与使用更加顺畅。
三、下载 Axios 包
1、下载Axios三包下面是三方仓库地址
OpenHarmony三方库中心仓https://ohpm.openharmony.cn/#/cn/home
2、如何正确导入Axios包
2-1、进入三方库
编辑
2-2、复制命令行
编辑
2-3、进入DevEcoStudio下载Axios(进入后我们可以快捷键 Ctrl+ ~ 打开终端拖动整个目录到终端运行 2-2 复制的命令行)
编辑
2-4、进入配置文件、添加网络请求
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
编辑
四、正确导入 Axios 包
- 进入三方库:就像进入 “宝库” 的特定区域寻找 Axios 这个 “宝藏”。
- 复制命令行:从三方库页面复制下载 Axios 所需的命令行,这相当于拿到了获取 “宝藏” 的 “钥匙”。
- 进入 DevEcoStudio 下载 Axios:打开 DevEcoStudio 开发环境,通过快捷键
Ctrl + ~打开终端,然后将整个项目目录拖动到终端,并运行刚才复制的命令行。这一步就像是用 “钥匙” 打开了存放 Axios 的 “宝箱”,将其下载到项目中。 - 进入配置文件、添加网络请求权限:在项目的配置文件中添加网络请求权限声明:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
这一步如同给应用颁发了一张 “网络通行证”,允许它进行网络请求操作。
五、封装 Axios 方法
封装方法一(全部)
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from "@ohos/axios";
import { BASE_URL, userSetting, UserSetting } from "../../../../Index";
import settings from "@ohos.settings";
import { promptAction, router } from "@kit.ArkUI";
// 1. 创建axios的实例对象
// 配置基础地址, 超时时间
export const instance = axios.create({
baseURL: BASE_URL,
timeout: 100000
});
// 2. 配置请求拦截器
instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
const token = userSetting.getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}, (error: AxiosError) => {
return Promise.reject(error);
});
// 3. 配置响应拦截器
instance.interceptors.response.use((res: AxiosResponse) => {
// 3.1 判断业务成功
if (res.data.code === 200) {
return res.data;
}
return Promise.reject(res.data);
}, (error: AxiosError) => {
if (error.response?.status === 401) {
promptAction.showToast({ message: '登录失败' });
userSetting.setToken('');
router.pushUrl({ url: 'pages/Login/Login' });
}
return Promise.reject(error);
});
// 4. 封装Http类
// 提供request方法
class Http {
request<ResponseData, RequestData = Object>(config: AxiosRequestConfig<RequestData>) {
return instance.request<null, ResponseData, RequestData>(config);
}
}
// 5. 创建并导出http实例对象
export const http = new Http();
-
导入相关模块:从
@ohos/axios导入axios库以及一些类型定义,这些类型定义就像是给代码的各个部分贴上了 “标签”,让它们的作用更加明确。同时还导入了项目中的基础 URL(BASE_URL)、用户设置相关的userSetting和UserSetting,以及@ohos.settings、@kit.ArkUI中的部分模块,为后续功能实现做准备。 -
创建 axios 实例:使用
axios.create方法创建一个axios实例instance,并设置了基础 URL(BASE_URL)和超时时间为 100000 毫秒(100 秒)。这就像是打造了一辆专门用于网络请求的 “汽车”,并为它设定了出发的 “基地” 和行驶的 “最长时间限制”。 -
配置请求拦截器:通过
instance.interceptors.request.use配置请求拦截器,它就像一个 “关卡”,在请求发送前对请求进行检查和处理。- 第一个回调函数会在请求发送前执行,从
userSetting中获取token,如果token存在,就将其添加到请求头的Authorization字段中,为请求 “贴上身份标签”。 - 第二个回调函数在请求发生错误时执行,以
Promise.reject的方式抛出错误,就像告诉调用者 “这条路走不通啦,出问题了”。
- 第一个回调函数会在请求发送前执行,从
-
配置响应拦截器:利用
instance.interceptors.response.use配置响应拦截器,这也是一个 “关卡”,不过是在响应返回时对响应进行处理。- 第一个回调函数在响应成功时执行,检查响应数据的
code字段是否为 200,如果是则返回响应数据,否则以Promise.reject的方式抛出响应数据,就像对 “货物” 进行检验,合格的就收下,不合格的就退回去。 - 第二个回调函数在响应发生错误时执行,如果错误状态码为 401(表示未授权),则显示提示框告知用户 “登录失败”,清除
token并跳转到登录页面,最后将错误以Promise.reject的方式抛出,这一系列操作就像是在发现 “货物” 有问题时,采取相应的措施并反馈给调用者。
- 第一个回调函数在响应成功时执行,检查响应数据的
-
封装 Http 类:定义一个
Http类,包含一个request方法。这个类就像是一个 “调度中心”,统一管理网络请求。request方法是一个泛型方法,接收两个泛型参数ResponseData和RequestData,分别表示响应数据类型和请求数据类型(默认值为Object)。- 该方法调用
instance.request方法发送请求,并返回请求的结果,就像 “调度中心” 安排 “汽车” 出发并等待它带回 “货物”。
-
导出 Http 实例:创建
Http类的一个实例http并导出,方便在其他地方使用封装好的请求方法,就像是将 “调度中心” 的使用权开放给其他模块。
封装方法二(部分)
export class RequestAxios {
static get<T>(url: string, params?: object): Promise<T> {
return instance.get<null, T>(url, { params });
}
static post<T>(url: string, data?: object): Promise<T> {
return instance.post<null, T>(url, data);
}
static delete<T>(url: string, params?: object): Promise<T> {
return instance.delete<null, T>(url, { params });
}
static put<T>(url: string, data?: object): Promise<T> {
return instance.put<null, T>(url, data);
}
}
-
定义 RequestAxios 类:这个类是对
axios实例instance的进一步封装,就像是给 “调度中心” 穿上了一件更便捷的 “外衣”,提供了四个静态方法,分别对应 HTTP 的四种常见请求方法:GET、POST、DELETE 和 PUT。 -
静态方法分析:
- GET 方法:
static get<T>(url: string, params?: object): Promise<T> {
return instance.get<null, T>(url, { params });
}
static关键字表明这是一个静态方法,可以直接通过RequestAxios.get调用,无需创建RequestAxios类的实例,就像给这个方法提供了一条 “快捷通道”。<T>是泛型参数,用于指定请求响应数据的类型。调用这个方法时,能依据实际情况指定具体的响应数据类型,就像给 “货物” 贴上了一个明确的 “标签”。url参数是请求的 URL 地址,类型为字符串,告诉 “汽车” 要去哪里获取 “货物”。params参数是可选的,类型为对象,用于传递请求的查询参数,就像是给 “汽车” 带上一些 “特殊要求”。instance.get<null, T>(url, { params })调用了之前创建的axios实例instance的get方法发起 GET 请求。null表示请求体的数据类型,这里不需要请求体所以为null;T是响应数据的类型。最后返回一个Promise,该Promise会在请求完成后解析为类型为T的响应数据,就像 “汽车” 带回了符合要求的 “货物”。- POST、DELETE 和 PUT 方法的原理与 GET 方法类似,只是调用的是
instance的相应请求方法,并根据不同请求方法的特点处理参数。
六、详细分析
Http 类
- 功能概述:
Http类主要是对axios实例instance进行了一层简单的封装,提供了一个通用的request方法。这个方法可以处理各种类型的 HTTP 请求,因为它接收的是一个AxiosRequestConfig对象,这个对象可以包含请求的所有配置信息,如请求方法、URL、参数、数据等。它就像是一个 “万能接口”,允许调用者根据具体需求来配置请求。 - 泛型使用:
request方法使用了泛型ResponseData和RequestData,分别表示响应数据类型和请求数据类型。调用时可以指定这两个泛型类型,以明确请求和响应的数据类型,让代码更加 “类型安全”,就像给 “货物” 和 “运输要求” 都贴上了准确的 “标签”。 - 灵活性与适用场景:具有较高的灵活性,因为它允许调用者完全自定义请求的配置,包括请求方法、请求头、超时时间等。但使用起来相对复杂,需要调用者对
AxiosRequestConfig有一定的了解。适用于需要统一管理请求配置的场景,代码复用主要体现在对请求配置的统一处理上。如果项目中有很多不同类型的请求,并且需要对请求配置进行统一的修改或扩展,使用Http类会更合适,就像在一个大型的 “运输系统” 中,需要对各种运输任务进行统一规划和管理。
RequestAxios 类
- 功能概述:
RequestAxios类对常见的 HTTP 请求方法(GET、POST、DELETE、PUT)进行了单独的封装,为每种请求方法提供了一个静态方法。它的目的是让调用者更方便地发起特定类型的请求,调用者只需传入必要的参数(如 URL、查询参数或请求体数据),而不需要手动配置AxiosRequestConfig对象,就像给调用者提供了几个 “一键操作” 的按钮,简化了请求发起的过程。 - 泛型使用:每个静态方法都使用了泛型
T,用于指定响应数据的类型。调用时可以根据实际情况指定T的具体类型,同样保证了代码的 “类型安全”。 - 便捷性与适用场景:更加便捷,调用者只需要关注请求的类型(GET、POST 等)、URL 和必要的参数,不需要手动配置请求方法和其他复杂的配置项。但灵活性相对较低,因为它只提供了四种常见的请求方法。适用于需要频繁发起常见 HTTP 请求的场景,代码复用主要体现在对特定请求方法的封装上。调用者可以直接使用封装好的方法,减少了重复编写请求代码的工作量,就像在一个小型的 “运输任务” 中,经常需要执行几种固定类型的运输,使用这种封装可以提高效率。
七、总结
Axios 集成三要素
1、安装命令:ohpm install @ohos/axios ,这是获取 Axios “宝藏工具” 的关键指令。
2、权限声明:
"requestPermissions": [{ "name": "ohos.permission.INTERNET" }]
为应用开启网络请求的 “大门”,确保能够进行网络通信。
3.、实例化配置:
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000
});
创建 axios 实例,为网络请求 “汽车” 设定 “出发基地” 和 “行驶限制”。
拦截器核心逻辑
1、请求拦截:
instance.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${userSetting.getToken()}`;
return config;
});
在请求发送前为其 “贴上身份标签”,确保请求的合法性。
2、 响应拦截:
instance.interceptors.response.use((res) => {
if (res.data.code!== 200) return Promise.reject(res.data);
return res.data;
}, (error) => {
if (error.response?.status === 401) {
// 跳转登录页并清除 Token
}
});
对响应 “货物” 进行检验,不合格的 “货物” 退回,并在特定错误情况下采取相应措施。
封装方案对比与选型指南
表格
| 场景 | 推荐方案 | 优势 | 示例代码 |
|---|---|---|---|
| 复杂业务,需统一管理 | Http 类 + 拦截器 | 灵活控制请求生命周期,支持全局日志、缓存、重试 | http.request<User>({ url: '/user' }) |
| 快速开发,接口标准化 | RequestAxios 静态方法 | 开箱即用,减少重复代码,类型安全 | RequestAxios.get<User>('/user', {id:1}) |
常见问题
-
网络权限失效:
- 现象:请求报错
INTERNET permission denied。就像应用被 “拦住”,无法通过网络 “大门”。 - 解决:检查
module.json5权限声明,确保应用在设置中已授权网络权限。这就像是检查 “大门” 的钥匙是否正确,以及是否被允许进入。
- 现象:请求报错
-
Token 未生效:
- 现象:请求头未携带
Authorization。就像 “身份标签” 没有贴好。 - 排查:确认
userSetting.getToken()返回值非空,拦截器逻辑未被覆盖。检查 “身份标签” 的获取和粘贴过程是否正确。
- 现象:请求头未携带
-
跨域问题 (CORS) :
- 现象:H5 页面调用接口报跨域错误。就像在不同 “区域” 之间通信遇到了阻碍。
- 解决:服务端配置
Access-Control-Allow-Origin,或使用 OpenHarmony 本地代理转发。为跨域通信搭建 “桥梁”。
-
TypeScript 类型污染:
- 现象:泛型类型
T推断错误。就像 “标签” 贴错了。 - 解决:明确定义接口响应类型。重新贴好正确的 “标签”。
- 现象:泛型类型
通过本文的介绍,相信你对在 Harmony OS 中集成与封装 Axios 有了更深入的了解。关于 Harmony OS 开发中更多的技术细节和实践经验,我会在后续博客中持续分享,感兴趣的话欢迎关注。对于本文介绍的内容,你有什么疑问或者想法吗?欢迎随时交流。