037-axios网络请求封装

📅 2026/7/22 3:58:02 👁️ 阅读次数 📝 编程学习
037-axios网络请求封装

037 — @ohos/axios 网络请求封装:构建可复用的 HTTP 客户端

简介

在鸿蒙应用开发中,网络请求是连接客户端与服务端的核心桥梁。MoneyTrack 项目基于@ohos/axios库,通过单例模式封装了一个高度可复用的 HTTP 客户端,统一管理 baseURL、超时配置、请求/响应拦截器等关键能力。这套封装不仅减少了重复代码,更通过拦截器机制实现了全局错误处理、Token 注入、超时重试和日志打点,为上层 33+ 个 API 端点提供了稳定、一致的网络通信基础。

核心知识点

1. Axios 实例创建与全局配置

通过axios.create()创建自定义实例,集中管理全局配置,避免每个请求单独拼写:

  • baseURL:统一设置服务端地址,支持通过环境变量切换 dev/prod 环境。
  • 超时设置(30000ms):30 秒超时阈值,平衡用户体验与网络等待。配合超时重试机制,进一步提升弱网下的请求成功率。
  • 请求头默认值:统一设置Content-Type: application/jsonAccept等通用头部。
constinstance=axios.create({baseURL:ApiConfig.getBaseUrl(),// 环境切换:dev/prodtimeout:30000,headers:{'Content-Type':'application/json'}});

2. 拦截器机制

拦截器是 Axios 最强大的扩展点。MoneyTrack 使用多个拦截器实现关注点分离,多个请求拦截器按注册顺序先注册先执行,多个响应拦截器按注册顺序先注册后执行

请求拦截器链路:请求拦截器①(Token注入)→ 请求拦截器②(日志打点)→ 发送网络请求 → 响应拦截器①(状态码解析)→ 响应拦截器②(错误分类处理)

请求拦截器:注入 Token + 日志打点
// 请求拦截器① — Token 注入instance.interceptors.request.use((config)=>{consttoken=AppStorage.get<string>('token');if(token){config.headers.Authorization=`Bearer${token}`;}returnconfig;},(error)=>Promise.reject(error));// 请求拦截器② — 日志打点instance.interceptors.request.use((config)=>{console.info(`[Network]${config.method?.toUpperCase()}${config.url}`);returnconfig;},(error)=>Promise.reject(error));
响应拦截器:解析 data + 错误分类处理
// 响应拦截器① — 状态码校验instance.interceptors.response.use((response:AxiosResponse)=>{if(response.status===200){returnPromise.resolve(response.data);}Logger.error('[Network]',`请求失败:${response.config.url}`,JSON.stringify(response.status));returnPromise.reject(response);},(error:BusinessError)=>{// 错误分类处理if(error.code==='ECONNABORTED'){// 超时错误returnhandleTimeoutRetry(error);}elseif(!error.response){// 断网错误ReminderUtil.showToast('网络异常,请检查网络连接');}Logger.error('[Network]',`请求失败:`,JSON.stringify(error));returnPromise.reject(error);});

3. 超时重试机制

对于超时或可恢复的网络错误,采用"最大重试次数 + 固定延迟"的策略自动重试:

asyncfunctionhandleTimeoutRetry(error:BusinessError,retryCount=3):Promise<any>{constconfig=error.config;if(!config||!config._retryCount){config._retryCount=0;}if(config._retryCount<retryCount){config._retryCount++;console.info(`[Network] 第${config._retryCount}次重试:${config.url}`);returnnewPromise((resolve)=>setTimeout(resolve,1000)).then(()=>instance.request(config));}returnPromise.reject(error);}

4. 环境切换

通过ApiConfig模块根据构建标识自动切换 baseURL,实现一套代码多环境部署:

exportclassApiConfig{staticgetBaseUrl():string{if(process.env.NODE_ENV==='production'){return'https://api.moneytrack.com';}return'https://dev-api.moneytrack.com';}}

请求拦截→发送→响应拦截完整链路

响应拦截器②错误分类处理响应拦截器①状态码解析后端服务Axios 发送请求请求拦截器②日志打点请求拦截器①Token 注入应用层 API响应拦截器②错误分类处理响应拦截器①状态码解析后端服务Axios 发送请求请求拦截器②日志打点请求拦截器①Token 注入应用层 APIalt[成功][失败]发起请求读取 Token 并注入 Header传递 config打印请求日志发送 HTTP 请求网络传输返回响应接收响应校验 status === 200传递 response.data返回业务数据传递错误分类处理(超时/断网/业务错误)Promise.reject

最佳实践

  1. Token 过期自动刷新:在响应拦截器中捕获 401 状态码,尝试调用刷新 Token 接口,成功后重放原始请求队列。
  2. 断网兜底:在网络不可用时,将请求暂存到离线队列,配合网络状态监听(见 041 篇)在网络恢复后自动重发。
  3. 拦截器顺序:多个请求拦截器按注册顺序依次执行;多个响应拦截器按注册顺序反向执行。需要先注入 Token 再打日志,因此 Token 拦截器先注册。
  4. 请求取消:使用axios.CancelTokenAbortController,在页面离开时取消未完成的请求,避免内存泄漏。

推荐参考文档

  • @ohos/axios API 参考
  • Axios 官方文档