HarmonyOS 网络请求第一步:从零封装一个 Axios 拦截器
注:适用版本(Harmony OS NEXT / 5.0 / API 12+ )
-
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"
}
],
3、封装Axios方法
3-1、封装方法一(全部),后续有相信代码分析
第一种封装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(config: AxiosRequestConfig) {
return instance.request(config)
}
}
// 5. 创建并导出http实例对象
export const http = new Http()
详细代码分析如下:
1、从 @ohos/axios
导入 axios
库以及一些类型定义,用于处理 HTTP 请求。
export const instance = axios.create({
baseURL:BASE_URL,
timeout: 100000
})
2、使用 axios.create
方法创建一个 axios
实例,设置了基础 URL 和超时时间为 100000 毫秒(即 100 秒)。
3、instance.interceptors.request.use
用于配置请求拦截器,它接收两个回调函数作为参数。
4、第一个回调函数在请求发送前执行,会从 userSetting
中获取 token,如果 token 存在,则将其添加到请求头的 Authorization
字段中。
5、第二个回调函数在请求发生错误时执行,会将错误以 Promise.reject
的方式抛出。
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)
})
6、instance.interceptors.response.use
用于配置响应拦截器,同样接收两个回调函数。
7、第一个回调函数在响应成功时执行,会检查响应数据的 code
字段是否为 200,如果是则返回响应数据,否则以 Promise.reject
的方式抛出响应数据。
8、第二个回调函数在响应发生错误时执行,如果错误状态码为 401(表示未授权),则显示提示框,清除 token 并跳转到登录页面,最后将错误以 Promise.reject
的方式抛出。
class Http {
request(config: AxiosRequestConfig) {
return instance.request(config)
}
}
9、定义了一个 Http
类,其中包含一个 request
方法。
10、request
方法是一个泛型方法,接收两个泛型参数 ResponseData
和 RequestData
,分别表示响应数据类型和请求数据类型(默认值为 Object
)。
11、该方法调用 instance.request
方法发送请求,并返回请求的结果。
export const http = new Http()
12、创建 Http
类的一个实例 http
并导出,方便在其他地方使用封装好的请求方法。
3-2 、封装方法二(部分)
在方法一种我们可以直服用Axios实例,和请求响应拦截器,方法二在方法一的基础上主要对axios的Http类做出了部分优化详细代码如下:
export class RequestAxios {
static get(url: string, params?: object): Promise {
return instance.get(url, { params })
}
static post(url: string, data?: object): Promise {
return instance.post(url, data)
}
static delete(url: string, params?: object): Promise {
return instance.delete(url, { params })
}
static put(url: string, data?: object): Promise {
return instance.put(url, data)
}
}
详细代码分析:RequestAxios
类是对之前创建的 axios
实例 instance
的进一步封装,它提供了四个静态方法,分别对应 HTTP 的四种常见请求方法:GET
、POST
、DELETE
和 PUT
。这样的封装使得在项目中发起不同类型的 HTTP 请求更加方便和统一。
1、t请求方法
static get(url: string, params?: object): Promise {
return instance.get(url, { params })
}
a.static
关键字表明 (get、post、delete、put)
是一个静态方法,意味着可以直接通过 RequestAxios.get
调用,无需创建 RequestAxios
类的实例。
b.
是泛型参数,用于指定请求响应数据的类型。调用这个方法时,能依据实际情况指定具体的响应数据类型。
c.url
参数是请求的 URL 地址,类型为字符串。
d.params
参数是可选的,类型为对象,用于传递请求的查询参数。
e.instance.
(get、post、delete、put)
调用了之前创建的 axios
实例 instance
的 get
方法发起 GET
请求。null
表示请求体的数据类型,这里不需要请求体所以为 null
;T
是响应数据的类型。最后返回一个 Promise
,该 Promise
会在请求完成后解析为类型为 T
的响应数据。
4、分析
Http类
1、该类主要是对axios实例instance进行了一层简单的封装,提供了一个通用的request方法,这个方法可以处理各种类型的HTTP请求,因为它接收的是一个AxiosRequestConfig对象,这个对象可以包含请求的所有配置信息,如请求方法、URL、参数、数据等。它的重点在于统一管理和发起请求,将请求的具体配置交给调用者。
2、request方法使用了泛型ResponseData和RequestData,分别表示响应数据类型和请求数据类型。调用时可以指定这两个泛型类型,以明确请求和响应的数据类型。
3、具有较高的灵活性,因为它允许调用者完全自定义请求的配置,包括请求方法、请求头、超时时间等。但使用起来相对复杂,需要调用者对AxiosRequestConfig有一定的了解。
4、适用于需要统一管理请求配置的场景,代码复用主要体现在对请求配置的统一处理上。如果项目中有很多不同类型的请求,并且需要对请求配置进行统一的修改或扩展,使用Http类会更合适。
RequestAxios类
1、该类对常见的HTTP请求方法(GET、POST、DELETE、PUT)进行了单独的封装,为每种请求方法提供了一个静态方法。它的目的是让调用者更方便地发起特定类型的请求,调用者只需传入必要的参数(如URL、查询参数或请求体数据),而不需要手动配置AxiosRequestConfig对象。
2、每个静态方法都使用了泛型T,用于指定响应数据的类型。调用时可以根据实际情况指定T的具体类型。
3、更加便捷,调用者只需要关注请求的类型(GET、POST等)、URL和必要的参数,不需要手动配置请求方法和其他复杂的配置项。但灵活性相对较低,因为它只提供了四种常见的请求方法。
4、适用于需要频繁发起常见HTTP请求的场景,代码复用主要体现在对特定请求方法的封装上。调用者可以直接使用封装好的方法,减少了重复编写请求代码的工作量。
5、总结
1、 Axios 集成三要素
安装命令
ohpm install @ohos/axios
权限声明
"requestPermissions": [{ "name": "ohos.permission.INTERNET" }]
实例化配置
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000
});
2、拦截器核心逻辑
请求拦截
instance.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${userSetting.getToken()}`;
return config;
});
响应拦截
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
}
});
3、封装方案对比与选型指南
场景 | 推荐方案 | 优势 | 示例代码 |
---|---|---|---|
复杂业务,需统一管理 | Http类 +拦截器 | 灵活控制请求生命周期,支持全局日志、缓存、重试 | http.request |
快速开发,接口标准化 | RequestAxios 静态方法 | 开箱即用,减少重复代码,类型安全 | RequestAxios.get |
4、常见问题
- 网络权限失效
- 现象:请求报错
INTERNET permission denied
。 - 解决:检查
module.json5
权限声明,确保应用在设置中已授权网络权限。
- 现象:请求报错
- Token 未生效
- 现象:请求头未携带
Authorization
。 - 排查:确认
userSetting.getToken()
返回值非空,拦截器逻辑未被覆盖。
- 现象:请求头未携带
- 跨域问题 (CORS)
- 现象:H5 页面调用接口报跨域错误。
- 解决:服务端配置
Access-Control-Allow-Origin
,或使用 OpenHarmony 本地代理转发。
- TypeScript 类型污染
- 现象:泛型类型
T
推断错误。 - 解决:明确定义接口响应类型。
- 现象:泛型类型
本文地址:https://www.vps345.com/14922.html