入门指南:在鸿蒙NEXT5.0中使用axios举行网络请求二次封装的实践与探究 ...

打印 上一主题 下一主题

主题 641|帖子 641|积分 1923

一、弁言

鸿蒙操作系统HarmonyOS作为新兴的跨设备平台,为开发者提供了广阔的创新空间。然而,由于其相对较新,许多开发者可能对其技能细节尚不熟悉,特别是在网络请求处理方面。axios作为一个成熟的HTTP客户端库,其强大的功能和灵活的配置使其成为处理网络请求的首选工具。在此,我也同样是初学者,我们共同砚习,如有任何不足之处,敬请各位不吝见教。
鸿蒙操作系统(OpenHarmony)的开发涉及到特定的工具和依赖管理。以下是在鸿蒙系统中封装和使用axios的一些步调和命令,以及如何使用ohpm(OpenHarmony Package Manager)来管理依赖。
ohpm常用命令

ohpm官方文档
  1. ohpm ls // 列出已安装的三方库
  2. ohpm install <package-name> // 安装三方库
  3. ohpm -v // 查询 ohpm cli 安装版本
  4. ohpm update <package-name>  更新依赖
  5. ohpm uninstall <package-name>  卸载依赖
  6. ohpm publish  发布包
复制代码
安装@ohos/axios

ohos_axios开源地址
ohos/axios是适用于鸿蒙系统的axios封装,你可以使用以下命令来安装它:
  1. ohpm install @ohos/axios
复制代码

安装完成后在 oh-package.json5 文件中的 dependencies 可以看到是否安装该依赖
  1. {
  2.   "modelVersion": "5.0.0",
  3.   "description": "Please describe the basic information.",
  4.   "dependencies": {
  5.     "@ohos/axios": "^2.2.4"
  6.   },
  7.   "devDependencies": {
  8.     "@ohos/hypium": "1.0.19",
  9.     "@ohos/hamock": "1.0.0"
  10.   },
  11.   "dynamicDependencies": {}
  12. }
复制代码

请求网络数据,起首需要申请权限,你需要在module.json5文件中申请网络访问权限。如下图所示。


二、封装步调

接下来则是封装 axios: 在你的项目中创建一个文件 文件名自界说
1. 导入依赖

导入所需的模块
  1. import axios, { InternalAxiosRequestConfig, AxiosResponse, AxiosError, AxiosInstance } from '@ohos/axios';
  2. import { promptAction } from '@kit.ArkUI';
  3. import { checkStatus } from './helper/checkStatus';
  4. import { logger } from '../utils/Logger';
复制代码
2. 界说响应数据结构

根据项目需求 以下为示例,界说ApiResponse接口:
  1. interface ApiResponse<T> { //根据项目实际项目修改
  2.   code?: number;
  3.   data: T | null;
  4.   message?: string;
  5. }
复制代码
3. 创建axios实例

创建一个axios实例,并配置基础信息:
  1. // 创建实例
  2. const instance: AxiosInstance = axios.create({
  3.   // 默认地址请求地址
  4.   baseURL: 'http://localhost:8617/', //修改为自己项目的实际地址
  5.   // 设置超时时间
  6.   timeout: 100000,
  7.   headers: {
  8.     'Content-Type': 'application/json;charset=utf-8',
  9.     'Content-Language': 'zh_CN'
  10.   },
  11. });
复制代码
4. 添加请求拦截器

在请求拦截器中,可以统一处理请求头、请求参数等:
  1. // 添加请求拦截器
  2. instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
  3.   // 对请求数据做点什么
  4.   const token = 'token....'
  5.   if (token) {
  6.     config.headers['Authorization'] = 'Bearer ' + token //设置token
  7.   }
  8.   return config
  9. }, (error: AxiosError) => {
  10.   // 对请求错误做些什么
  11.   return Promise.reject(error)
  12. })
复制代码
5. 添加响应拦截器

在响应拦截器中,可以统一处理响应数据、错误提示等: checkStatus文件在后面展示补充
  1. // 添加响应拦截器 错误统一处理等
  2. instance.interceptors.response.use((response: AxiosResponse) => {
  3.   // 对响应数据做点什么
  4.   // 下面配置根据系统返回来配置的,不同的系统配置不同
  5.   if (response.data.code == 200) { // 这里是举例 要根据自己项目的实际情况进行处理
  6.     promptAction.showToast({
  7.       //用到了 @kit.ArkUI 的 promptAction进行系统弹窗提示
  8.       message: response.data.massage,
  9.       duration: 2000,
  10.       alignment: Alignment.Center
  11.     });
  12.     logger.debug("请求成功", JSON.stringify(response))
  13.     return Promise.reject(response.data);
  14.   } else {
  15.     // 根据不同的错误码进行不同的处理
  16.     // promptAction.showToast({
  17.     //   message: response.data.message || '请求失败,请稍后重试',
  18.     //   duration: 2000,
  19.     //   alignment: Alignment.Center
  20.     // });
  21.     logger.error("Error", JSON.stringify(response))
  22.     // return Promise.reject(response);
  23.   }
  24.   return response
  25. }, (error: AxiosError) => {
  26.   // 请求超时 && 网络错误单独判断,没有 response
  27.   if (error.message.indexOf("timeout") !== -1) {
  28.     promptAction.showToast({ message: "请求超时!请您稍后重试" });
  29.   }
  30.   if (error.message.indexOf("Network Error") !== -1) {
  31.     promptAction.showToast({ message: "网络错误!请您稍后重试" });
  32.   }
  33.   console.log("AxiosError", JSON.stringify(error.response))
  34.   // 根据服务器响应的错误状态码,做不同的处理
  35.   const status = error.response?.status;
  36.   console.log('status', status)
  37.   if (status) {
  38.     checkStatus(status);
  39.   }
  40.   logger.error("error", JSON.stringify(error))
  41.   return Promise.reject(error)
  42. })
复制代码
6. 补充引入的文件 checkStatus 和 logger

  1. // Logger.ets
  2. import { hilog } from '@kit.PerformanceAnalysisKit';
  3. const LOGGER_PREFIX: string = 'interview_success_logger';
  4. class Logger {
  5.   private domain: number;
  6.   private prefix: string;
  7.   private format: string = '%{public}s, %{public}s';
  8.   constructor(prefix: string = '', domain: number = 0x0000) {
  9.     this.prefix = prefix;
  10.     this.domain = domain;
  11.   }
  12.   debug(...args: string[]): void {
  13.     hilog.debug(this.domain, this.prefix, this.format, args);
  14.   }
  15.   info(...args: string[]): void {
  16.     hilog.info(this.domain, this.prefix, this.format, args);
  17.   }
  18.   warn(...args: string[]): void {
  19.     hilog.warn(this.domain, this.prefix, this.format, args);
  20.   }
  21.   error(...args: string[]): void {
  22.     hilog.error(this.domain, this.prefix, this.format, args);
  23.   }
  24. }
  25. export const logger =  new Logger(LOGGER_PREFIX, 0x1234);
复制代码
  1. // checkStatus.ets
  2. import { promptAction } from '@kit.ArkUI';
  3. /**
  4. * @description: 校验网络请求状态码
  5. * @param {Number} status
  6. * @return void
  7. */
  8. export const checkStatus = (status: number) => {
  9.   switch (status) {
  10.     case 400:
  11.       promptAction.showToast({ message: "请求失败!请您稍后重试" })
  12.       break;
  13.     case 401:
  14.       promptAction.showToast({ message: "登录失效!请您重新登录" })
  15.       break;
  16.     case 403:
  17.       promptAction.showToast({ message: "当前账号无权限访问!" })
  18.       break;
  19.     case 404:
  20.       promptAction.showToast({ message: "你所访问的资源不存在!" })
  21.       break;
  22.     case 405:
  23.       promptAction.showToast({ message: "请求方式错误!请您稍后重试" })
  24.       break;
  25.     case 408:
  26.       promptAction.showToast({ message: "请求超时!请您稍后重试" })
  27.       break;
  28.     case 500:
  29.       promptAction.showToast({ message: "服务异常!" })
  30.       break;
  31.     case 502:
  32.       promptAction.showToast({ message: "网关错误!" })
  33.       break;
  34.     case 503:
  35.       promptAction.showToast({ message: "服务不可用!" })
  36.       break;
  37.     case 504:
  38.       promptAction.showToast({ message: "网关超时!" })
  39.       break;
  40.     default:
  41.       promptAction.showToast({ message: "请求失败!" })
  42.   }
  43. };
复制代码
6. 封装请求方法

创建一个RequestHttp类,封装get、post、delete、put等方法:
  1. // 封装请求方法
  2. class RequestHttp {
  3.   get<T>(url: string, params?: object): Promise<ApiResponse<T>> {
  4.     return instance.get<null, ApiResponse<T>>(url, { params })
  5.   }
  6.   // 封装post方法
  7.   post<T>(url: string, data?: object): Promise<ApiResponse<T>> {
  8.     return instance.post<null, ApiResponse<T>>(url, data)
  9.   }
  10.   // 封装delete方法
  11.   delete<T>(url: string, data?: object): Promise<ApiResponse<T>> {
  12.     return instance.delete<null, ApiResponse<T>>(url, data)
  13.   }
  14.   // 封装put方法
  15.   put<T>(url: string, data?: object): Promise<ApiResponse<T>> {
  16.     return instance.put<null, ApiResponse<T>>(url, data)
  17.   }
  18. }
  19. export const http = new RequestHttp();
复制代码
以上则是对axios的基础封装,根据项目需要可以自行对其修改,例如添加上传、下载文件的方法,支持取消请求等。
7. 代码示例示范调用

界说接口文件
  1. import { http } from "../api/index";
  2. interface CardNoParams{
  3.   name:string;
  4.   cardNo:string|number;
  5. }
  6. interface ApiResponse { //根据项目实际项目修改
  7.   code?: number;
  8.   data: object | null;
  9.   message?: string;
  10. }
  11. // 根据姓名身份证查询
  12. export function viewByNameAndCardNo(data:CardNoParams){
  13.   return http.post<ApiResponse>("/yjzgbtyj/viewCardNo", data)
  14. }
复制代码
  1. import { viewByNameAndCardNo } from '../../api/serviceGuide'
  2. dialogController: CustomDialogController = new CustomDialogController({
  3.   builder: CustomContentDialog({
  4.     primaryTitle: '请输入信息', // 弹出框标题
  5.     secondaryTitle: '', // 弹出框辅助文本
  6.     contentBuilder: () => {
  7.       this.buildContent();
  8.     },
  9.     buttons: [
  10.       {
  11.         value: '确定',
  12.         buttonStyle: ButtonStyleMode.TEXTUAL,
  13.         action: async () => {
  14.           if (!this.cardNo || !this.name) {
  15.             return promptAction.showToast({ message: "请输入完整的身份证号码和姓名" })
  16.           }
  17.           const res = await viewByNameAndCardNo({name: this.name, cardNo: this.cardNo})
  18.           console.log('res',JSON.stringify(res))
  19.           if (res.code === 200) {
  20.             console.log('result',JSON.stringify(res))
  21.           }else{
  22.             console.log('请求失败',JSON.stringify(res))
  23.             promptAction.showToast({ message: "查询不到该用户信息,请核对后重新输入!" })
  24.           }
  25.         }
  26.       },
  27.       {
  28.         value: '取消',
  29.         buttonStyle: ButtonStyleMode.TEXTUAL, role: ButtonRole.ERROR
  30.       }
  31.     ],
  32.   }),
  33.   alignment: DialogAlignment.Center,
  34.   cornerRadius: 10,
  35. });
复制代码
五、总结

本文详细先容了在鸿蒙系统中使用axios举行网络请求的封装与优化。通过封装,我们可以提高代码的可维护性、可读性,低落开发成本。在现实项目中,开发者可以根据具体需求举行相应的调整和优化。希望本文对您在鸿蒙系统开发过程中有所帮助。

   原文链接:https://juejin.cn/post/7435610446604828709

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

李优秀

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表