您的位置:首页 > 游戏 > 手游 > 青岛自助建站软件_南京百度_百度知道下载安装_百度快速排名案例

青岛自助建站软件_南京百度_百度知道下载安装_百度快速排名案例

2024/12/22 20:01:14 来源:https://blog.csdn.net/qq8864/article/details/144216260  浏览:    关键词:青岛自助建站软件_南京百度_百度知道下载安装_百度快速排名案例
青岛自助建站软件_南京百度_百度知道下载安装_百度快速排名案例

在现代应用开发中,网络请求是不可或缺的一部分。Axios库非常流行,而在HarmonyOS NEXT中,Axios库依然可用,可使用Axios库进行网络请求,可以极大地简化开发者的工作。通过对Axios的封装,不仅提升了代码的可维护性和可读性,还提供了一系列便捷的功能。本文将介绍Axios网络库的封装及其优点,帮助开发者在HarmonyOS NEXT环境下实现高效的网络请求。

axios三方库介绍

@ohos/axios是基于Axios原库v1.3.4版本为HarmonyOS/OpenHarmony适配的三方库,是一个基于promise的网络请求库,可以运行node.js和浏览器中,沿用其现有用法和特性。

•http请求

•Promise API

•request和response拦截器

•转换request和response的data数据

•自动转换JSON data数据 

 axios三方库安装

在项目的根目录下,命令行执行以下命令即可:

ohpm install @ohos/axios

 axios三方库封装的意义

对axios进行封装的意义在于提供更高层次的抽象,以便简化网络请求的使用和管理。以下是一些具体的理由:

1.统一接口:封装后,可以统一管理所有的网络请求接口,使得在应用中调用网络请求时更加一致,减少重复代码。

2.简化配置:封装可以避免每次请求都需要重复配置相似的参数(例如headers、请求方式等),通过配置对象直接传入更简洁。

3.请求和响应拦截器:封装允许在发送请求之前或收到响应之后,对请求或响应进行处理,比如添加公共的请求头、处理错误、数据格式化等。

4.错误处理:通过自定义的错误处理机制,可以实现统一的错误处理逻辑,比如根据状态码处理特定的错误(例如401未登录、403权限不足等)。

5.增强功能:可以根据项目需求添加额外的功能,例如显示加载状态、处理用户登录状态等。

6.提高可维护性:将网络请求相关的逻辑集中管理,可以让代码更加清晰,降低维护成本。

7.支持特定业务需求:可根据实际的业务需求扩展功能,比如提供缓存机制、重试机制等,增强请求的灵活性。

封装后的使用效果

//axiosClient.ets
//author:csdn猫哥(blog.csdn.net/qq8864)import {axiosClient,HttpPromise} from '../../utils/axiosClient';
import { ZhiNewsRespData,ZhiDetailRespData, HotMovieReq, MovieRespData } from '../bean/ApiTypes';// 获取知乎列表页api接口
export const getZhiHuNews = (date:string): HttpPromise<ZhiNewsRespData> => axiosClient.get({url:'/zhihunews/'+date});// 获取知乎详情页api接口
export const getZhiHuDetail = (id:string): HttpPromise<ZhiDetailRespData> => axiosClient.get({url:'/zhihudetail/'+id});// 获取热门影视接口,仅作为post的使用示例,未使用
export const getHotMovie = (req:HotMovieReq): HttpPromise<MovieRespData> => axiosClient.post({url:'/hotmovie',data:req});// 使用举例:
/*getHotMovie({start:1,count:2,city:'郑州'}).then((res) => {Log.debug(res.data.message)Log.debug("request","res.data.code:%{public}d",res.data.code)}).catch((err: BusinessError) => {Log.debug("request","err.data.code:%d",err.code)Log.debug("request",err.message)});*/

可以看出,封装后接口的使用清晰简单直观,一行代码一个接口,风格统一,参数简单整洁。

封装的实现过程

//axiosClient.ets
//author:csdn猫哥(blog.csdn.net/qq8864)
import axios, { AxiosError, AxiosInstance, AxiosRequestHeaders, AxiosResponse, InternalAxiosRequestConfig } from "@ohos/axios";interface HttpResponse<T> {data: T;status: number;statusText: string;config: HttpRequestConfig;
}export type HttpPromise<T> = Promise<HttpResponse<T>>;interface InterceptorHooks {requestInterceptor?: (config: HttpRequestConfig) => Promise<HttpRequestConfig>;requestInterceptorCatch?: (error: any) => any;responseInterceptor?: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>;responseInterceptorCatch?: (error: any) => any;
}// @ts-ignore
interface HttpRequestConfig extends InternalAxiosRequestConfig {showLoading?: boolean; // 是否展示请求loadingcheckResultCode?: boolean; // 是否检验响应结果码checkLoginState?: boolean; // 校验用户登陆状态needJumpToLogin?: boolean; // 是否需要跳转到登陆页面interceptorHooks?: InterceptorHooks; // 拦截器headers?: AxiosRequestHeaders;errorHandler?: (error: any) => void; // 错误处理
}export class AxiosHttpRequest {config: HttpRequestConfig;interceptorHooks?: InterceptorHooks;instance: AxiosInstance;constructor(options: HttpRequestConfig) {this.config = options;this.interceptorHooks = options.interceptorHooks;this.instance = axios.create(options);this.setupInterceptor();}setupInterceptor(): void {this.instance.interceptors.request.use(this.interceptorHooks?.requestInterceptor,this.interceptorHooks?.requestInterceptorCatch,);this.instance.interceptors.response.use(this.interceptorHooks?.responseInterceptor,this.interceptorHooks?.responseInterceptorCatch,);}request<T = any>(config: HttpRequestConfig): HttpPromise<T> {return new Promise<HttpResponse<T>>((resolve, reject) => {this.instance.request<any, HttpResponse<T>>(config).then(res => {resolve(res);}).catch(err => {const errorHandler = config.errorHandler || errorHandlerDefault;errorHandler(err);reject(err);});});}get<T = any>(config: HttpRequestConfig): HttpPromise<T> {return this.request({ ...config, method: 'GET' });}post<T = any>(config: HttpRequestConfig): HttpPromise<T> {return this.request({ ...config, method: 'POST' });}delete<T = any>(config: HttpRequestConfig): HttpPromise<T> {return this.request({ ...config, method: 'DELETE' });}patch<T = any>(config: HttpRequestConfig): HttpPromise<T> {return this.request({ ...config, method: 'PATCH' });}
}function errorHandlerDefault(error: any) {if (error instanceof AxiosError) {// 处理Axios的错误}// 处理其他类型的错误
}export default AxiosHttpRequest;

 如何使用

 上述封装仅是统一了接口访问风格,但还不便直接使用。可以再建一个全局单例的工具类使用:

//axiosClient.ets
//author:csdn猫哥(blog.csdn.net/qq8864)
import {AxiosHttpRequest,HttpPromise} from './axiosHttp'
import {AxiosRequestHeaders,AxiosError } from '@ohos/axios';
import { Log } from './logutil';
import { promptAction } from "@kit.ArkUI";function showToast(msg:string){Log.debug(msg)promptAction.showToast({ message: msg })
}function showLoadingDialog(msg:string){Log.debug(msg)promptAction.showToast({ message: msg })
}function hideLoadingDialog() {}
/*** axios请求客户端创建*/
const axiosClient = new AxiosHttpRequest({baseURL: "http://175.178.126.10:8000/api/v1",timeout: 10 * 1000,checkResultCode: false,showLoading:true,headers: {'Content-Type': 'application/json'} as AxiosRequestHeaders,interceptorHooks: {requestInterceptor: async (config) => {// 在发送请求之前做一些处理,例如打印请求信息Log.debug('网络请求Request 请求方法:', `${config.method}`);Log.debug('网络请求Request 请求链接:', `${config.url}`);Log.debug('网络请求Request Params:', `\n${JSON.stringify(config.params)}`);Log.debug('网络请求Request Data:', `${JSON.stringify(config.data)}`);axiosClient.config.showLoading = config.showLoadingif (config.showLoading) {showLoadingDialog("加载中...")}if (config.checkLoginState) {//let hasLogin = await StorageUtils.get(StorageKeys.USER_LOGIN, false)//Log.debug('网络请求Request 登录状态校验>>>', `${hasLogin.toString()}`);// if (hasLogin) {//   return config// } else {//   if (config.needJumpToLogin) {//     //Router.push(RoutePath.TestPage)//   }//   throw new AxiosError("请登录")// }}return config;},requestInterceptorCatch: (err) => {Log.error("网络请求RequestError", err.toString())if (axiosClient.config.showLoading) {hideLoadingDialog()}return err;},responseInterceptor: (response) => {//优先执行自己的请求响应拦截器,在执行通用请求request的if (axiosClient.config.showLoading) {hideLoadingDialog()}Log.debug('网络请求响应Response:', `\n${JSON.stringify(response.data)}`);if (response.status === 200) {// @ts-ignoreconst checkResultCode = response.config.checkResultCodeif (checkResultCode && response.data.errorCode != 0) {showToast(response.data.errorMsg)return Promise.reject(response)}return Promise.resolve(response);} else {return Promise.reject(response);}},responseInterceptorCatch: (error) => {if (axiosClient.config.showLoading) {hideLoadingDialog()}Log.error("网络请求响应异常", error.toString());errorHandler(error);return Promise.reject(error);},}
});function errorHandler(error: any) {if (error instanceof AxiosError) {//showToast(error.message)} else if (error != undefined && error.response != undefined && error.response.status) {switch (error.response.status) {// 401: 未登录// 未登录则跳转登录页面,并携带当前页面的路径// 在登录成功后返回当前页面,这一步需要在登录页操作。case 401:break;// 403 token过期// 登录过期对用户进行提示// 清除本地token和清空vuex中token对象// 跳转登录页面case 403://showToast("登录过期,请重新登录")// 清除token// localStorage.removeItem('token');break;// 404请求不存在case 404://showToast("网络请求不存在")break;// 其他错误,直接抛出错误提示default://showToast(error.response.data.message)}}
}export  {axiosClient,HttpPromise};

封装后的使用

import {axiosClient,HttpPromise} from '../../utils/axiosClient';
import { ZhiNewsRespData,ZhiDetailRespData, HotMovieReq, MovieRespData } from '../bean/ApiTypes';// 获取知乎列表页api接口
export const getZhiHuNews = (date:string): HttpPromise<ZhiNewsRespData> => axiosClient.get({url:'/zhihunews/'+date});// 获取知乎详情页api接口
export const getZhiHuDetail = (id:string): HttpPromise<ZhiDetailRespData> => axiosClient.get({url:'/zhihudetail/'+id});// 获取热门影视接口,仅作为post的使用示例,未使用
export const getHotMovie = (req:HotMovieReq): HttpPromise<MovieRespData> => axiosClient.post({url:'/hotmovie',data:req});// 使用举例:
/*getHotMovie({start:1,count:2,city:'郑州'}).then((res) => {Log.debug(res.data.message)Log.debug("request","res.data.code:%{public}d",res.data.code)}).catch((err: BusinessError) => {Log.debug("request","err.data.code:%d",err.code)Log.debug("request",err.message)});*/

一行代码写好一个接口,清晰直观。但是接口相关的包体还是需要定义好的。定义接口类型字段麻烦吗?参见博主的根据json自动生成ts代码神器工具介绍。

//===知乎日报接口包体定义
export interface ZhiNewsItem {id:string;image:string;title:string;url:string;hint:string;date: string;isShowDivider?: boolean;}
export interface ZhiNewsRespData {code: number;message: string;stories: Array<ZhiNewsItem>;top_stories: Array<ZhiNewsItem>;date: string;
}export type ZhiDetailItem={types:string;value:string;
}
export interface ZhiDetailRespData {code: number;message: string;content: Array<ZhiDetailItem>;title: string;author: string;bio: string;avatar: string;image: string;more: string;}

总结

通过对Axios的封装,我们可以在HarmonyOS NEXT应用开发中实现更高效、更整洁的网络请求处理。封装不仅提升了代码的可维护性和可读性,还提供了简洁、一致的使用体验。无论你是初学者还是经验丰富的开发者,都可以通过这种封装方式大幅度提高开发效率。在未来的开发中,我们推荐您使用这种封装技术来处理网络请求,以便更好地适应快速发展的移动应用开发需求。

作者:csdn猫哥 blog.csdn.net/qq8864,转载请注明出处。

团队:坚果派
团队介绍:坚果派由坚果等人创建,团队拥有12个华为HDE带领热爱HarmonyOS/OpenHarmony的开发者,以及若干其他领域的三十余位万粉博主运营。专注于分享HarmonyOS/OpenHarmony、ArkUI-X、元服务、仓颉。团队成员聚集在北京,上海,南京,深圳,广州,宁夏等地,目前已开发鸿蒙原生应用,三方库60+,欢迎交流。

写在最后

最后,推荐下笔者的业余开源app影视项目“爱影家”,推荐分享给与我一样喜欢免费观影的朋友。
注:因涉及免费观影,该项目仅限于学习研究使用!请勿用于其他用途!

开源地址:爱影家app开源项目介绍及源码

https://gitee.com/yyz116/imovie

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com