- 作者:老汪软件技巧
- 发表时间:2024-11-11 15:03
- 浏览量:
一、引言
鸿蒙操作系统HarmonyOS作为新兴的跨设备平台,为开发者提供了广阔的创新空间。然而,由于其相对较新,许多开发者可能对其技术细节尚不熟悉,特别是在网络请求处理方面。axios作为一个成熟的HTTP客户端库,其强大的功能和灵活的配置使其成为处理网络请求的首选工具。在此,我也同样是初学者,我们共同学习,如有任何不足之处,敬请各位不吝赐教。
鸿蒙操作系统(OpenHarmony)的开发涉及到特定的工具和依赖管理。以下是在鸿蒙系统中封装和使用axios的一些步骤和命令,以及如何使用ohpm(OpenHarmony Package Manager)来管理依赖。
ohpm常用命令
ohpm官方文档
ohpm ls // 列出已安装的三方库
ohpm install // 安装三方库
ohpm -v // 查询 ohpm cli 安装版本
ohpm update 更新依赖
ohpm uninstall 卸载依赖
ohpm publish 发布包
安装@ohos/axios
ohos/axios是适用于鸿蒙系统的axios封装,你可以使用以下命令来安装它:
ohpm install @ohos/axios
安装完成后在 oh-package.json5 文件中的 dependencies 可以看到是否安装该依赖
{
"modelVersion": "5.0.0",
"description": "Please describe the basic information.",
"dependencies": {
"@ohos/axios": "^2.2.4"
},
"devDependencies": {
"@ohos/hypium": "1.0.19",
"@ohos/hamock": "1.0.0"
},
"dynamicDependencies": {}
}
请求网络数据,首先需要申请权限,你需要在module.json5文件中申请网络访问权限。如下图所示。
二、封装步骤
接下来则是封装 axios:在你的项目中创建一个文件 文件名自定义
1. 导入依赖
导入所需的模块
import axios, { InternalAxiosRequestConfig, AxiosResponse, AxiosError, AxiosInstance } from '@ohos/axios';
import { promptAction } from '@kit.ArkUI';
import { checkStatus } from './helper/checkStatus';
import { logger } from '../utils/Logger';
2. 定义响应数据结构
根据项目需求 以下为示例,定义ApiResponse接口:
interface ApiResponse { //根据项目实际项目修改
code?: number;
data: T | null;
message?: string;
}
3. 创建axios实例
创建一个axios实例,并配置基础信息:
// 创建实例
const instance: AxiosInstance = axios.create({
// 默认地址请求地址
baseURL: 'http://localhost:8617/', //修改为自己项目的实际地址
// 设置超时时间
timeout: 100000,
headers: {
'Content-Type': 'application/json;charset=utf-8',
'Content-Language': 'zh_CN'
},
});
4. 添加请求拦截器
在请求拦截器中,可以统一处理请求头、请求参数等:
// 添加请求拦截器
instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
// 对请求数据做点什么
const token = 'token....'
if (token) {
config.headers['Authorization'] = 'Bearer ' + token //设置token
}
return config
}, (error: AxiosError) => {
// 对请求错误做些什么
return Promise.reject(error)
})
5. 添加响应拦截器
在响应拦截器中,可以统一处理响应数据、错误提示等:checkStatus文件在后面展示补充
// 添加响应拦截器 错误统一处理等
instance.interceptors.response.use((response: AxiosResponse) => {
// 对响应数据做点什么
// 下面配置根据系统返回来配置的,不同的系统配置不同
if (response.data.code == 200) { // 这里是举例 要根据自己项目的实际情况进行处理
promptAction.showToast({
//用到了 @kit.ArkUI 的 promptAction进行系统弹窗提示
message: response.data.massage,
duration: 2000,
alignment: Alignment.Center
});
logger.debug("请求成功", JSON.stringify(response))
return Promise.reject(response.data);
} else {
// 根据不同的错误码进行不同的处理
// promptAction.showToast({
// message: response.data.message || '请求失败,请稍后重试',
// duration: 2000,
// alignment: Alignment.Center
// });
logger.error("Error", JSON.stringify(response))
// return Promise.reject(response);
}
return response
}, (error: AxiosError) => {
// 请求超时 && 网络错误单独判断,没有 response
if (error.message.indexOf("timeout") !== -1) {
promptAction.showToast({ message: "请求超时!请您稍后重试" });
}
if (error.message.indexOf("Network Error") !== -1) {
promptAction.showToast({ message: "网络错误!请您稍后重试" });
}
console.log("AxiosError", JSON.stringify(error.response))
// 根据服务器响应的错误状态码,做不同的处理
const status = error.response?.status;
console.log('status', status)
if (status) {
checkStatus(status);
}
logger.error("error", JSON.stringify(error))
return Promise.reject(error)
})
6. 补充引入的文件 checkStatus 和 logger
// Logger.ets
import { hilog } from '@kit.PerformanceAnalysisKit';
const LOGGER_PREFIX: string = 'interview_success_logger';
class Logger {
private domain: number;
private prefix: string;
private format: string = '%{public}s, %{public}s';
constructor(prefix: string = '', domain: number = 0x0000) {
this.prefix = prefix;
this.domain = domain;
}
debug(...args: string[]): void {
hilog.debug(this.domain, this.prefix, this.format, args);
}
info(...args: string[]): void {
hilog.info(this.domain, this.prefix, this.format, args);
}
warn(...args: string[]): void {
hilog.warn(this.domain, this.prefix, this.format, args);
}
error(...args: string[]): void {
hilog.error(this.domain, this.prefix, this.format, args);
}
}
export const logger = new Logger(LOGGER_PREFIX, 0x1234);
// checkStatus.ets
import { promptAction } from '@kit.ArkUI';
/**
* @description: 校验网络请求状态码
* @param {Number} status
* @return void
*/
export const checkStatus = (status: number) => {
switch (status) {
case 400:
promptAction.showToast({ message: "请求失败!请您稍后重试" })
break;
case 401:
promptAction.showToast({ message: "登录失效!请您重新登录" })
break;
case 403:
promptAction.showToast({ message: "当前账号无权限访问!" })
break;
case 404:
promptAction.showToast({ message: "你所访问的资源不存在!" })
break;
case 405:
promptAction.showToast({ message: "请求方式错误!请您稍后重试" })
break;
case 408:
promptAction.showToast({ message: "请求超时!请您稍后重试" })
break;
case 500:
promptAction.showToast({ message: "服务异常!" })
break;
case 502:
promptAction.showToast({ message: "网关错误!" })
break;
case 503:
promptAction.showToast({ message: "服务不可用!" })
break;
case 504:
promptAction.showToast({ message: "网关超时!" })
break;
default:
promptAction.showToast({ message: "请求失败!" })
}
};
6. 封装请求方法
创建一个RequestHttp类,封装get、post、delete、put等方法:
// 封装请求方法
class RequestHttp {
get(url: string, params?: object): Promise<ApiResponse> {
return instance.get<null, ApiResponse>(url, { params })
}
// 封装post方法
post(url: string, data?: object): Promise<ApiResponse> {
return instance.post<null, ApiResponse>(url, data)
}
// 封装delete方法
delete(url: string, data?: object): Promise<ApiResponse> {
return instance.delete<null, ApiResponse>(url, data)
}
// 封装put方法
put(url: string, data?: object): Promise<ApiResponse> {
return instance.put<null, ApiResponse>(url, data)
}
}
export const http = new RequestHttp();
以上则是对axios的基础封装,根据项目需要可以自行对其修改,例如添加上传、下载文件的方法,支持取消请求等。
7. 代码示例示范调用
定义接口文件
import { http } from "../api/index";
interface CardNoParams{
name:string;
cardNo:string|number;
}
interface ApiResponse { //根据项目实际项目修改
code?: number;
data: object | null;
message?: string;
}
// 根据姓名身份证查询
export function viewByNameAndCardNo(data:CardNoParams){
return http.post<ApiResponse>("/yjzgbtyj/viewCardNo", data)
}
import { viewByNameAndCardNo } from '../../api/serviceGuide'
dialogController: CustomDialogController = new CustomDialogController({
builder: CustomContentDialog({
primaryTitle: '请输入信息', // 弹出框标题
secondaryTitle: '', // 弹出框辅助文本
contentBuilder: () => {
this.buildContent();
},
buttons: [
{
value: '确定',
buttonStyle: ButtonStyleMode.TEXTUAL,
action: async () => {
if (!this.cardNo || !this.name) {
return promptAction.showToast({ message: "请输入完整的身份证号码和姓名" })
}
const res = await viewByNameAndCardNo({name: this.name, cardNo: this.cardNo})
console.log('res',JSON.stringify(res))
if (res.code === 200) {
console.log('result',JSON.stringify(res))
}else{
console.log('请求失败',JSON.stringify(res))
promptAction.showToast({ message: "查询不到该用户信息,请核对后重新输入!" })
}
}
},
{
value: '取消',
buttonStyle: ButtonStyleMode.TEXTUAL, role: ButtonRole.ERROR
}
],
}),
alignment: DialogAlignment.Center,
cornerRadius: 10,
});
五、总结
本文详细介绍了在鸿蒙系统中使用axios进行网络请求的封装与优化。通过封装,我们可以提高代码的可维护性、可读性,降低开发成本。在实际项目中,开发者可以根据具体需求进行相应的调整和优化。希望本文对您在鸿蒙系统开发过程中有所帮助。