HarmonyOS 7 三方网络库类型安全封装:连载01(共04篇)【共创稿事节】
HarmonyOS 7 三方网络库类型安全封装:连载01(共04篇)【共创稿事节】
访客入场登记看似只是四个输入框和一个提交按钮,真正容易出问题的地方却藏在网络层:字段变更后调用处继续使用旧结构、服务端返回业务错误但页面显示成功、请求超时后用户反复点击。把三方请求直接写进 ArkUI 页面,会让表单校验、HTTP 协议、业务反馈三种逻辑相互缠绕。下面围绕一张活动访客表单建立独立的类型化网络访问层,后续的离线队列、重试和同步恢复都沿用同一份契约。

从依赖版本开始固定实现基础
HarmonyOS 的三方网络访问可以选用社区维护的 @ohos/axios。这一移植库与浏览器端 npm 包并非同一个安装目标,工程使用 OHPM 安装。OpenHarmony-SIG/ohos_axios 的更新记录明确列出正式发布的 v2.2.4,同时列出后续候选版本;这里选择确定的 2.2.4 作为工程版本基线,而不是使用浮动范围。
ohpm install @ohos/axios@2.2.4
ohpm list
模块级 entry/oh-package.json5 的 dependencies 应采用固定版本号:
{
"dependencies": {
"@ohos/axios": "2.2.4"
}
}
已有工程需要将这段依赖项合并进原配置,不应覆盖工程现存的构建字段。检查 oh-package-lock.json5 中的解析结果,使同一仓库里的不同模块遵守一致版本。依赖更新应作为一次独立的代码审查项;直接用通配符升级会增加接口类型变化带来的维护成本。
网络访问还需要在 entry/src/main/module.json5 的 module.requestPermissions 中包含 ohos.permission.INTERNET。下面是相关配置片段:
{
"module": {
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" }
]
}
}
请求地址使用业务后端提供的 HTTPS 域名。https://api.example.com 是配置位置的示例值,实际工程由不同环境的构建配置或受控应用配置提供;也要处理证书校验失败和服务端接口变更,而非把网络故障归为用户输入错误。
数据契约放在页面之外
访客登记的数据至少包含联系人、联系电话、来访事由与日期。我们将请求体与返回体分离,并规定服务端响应有统一的 code、message 和 data。这样页面无需知道第三方库如何包装 response,只依赖清晰的业务结果。文件可放在 entry/src/main/ets/model/VisitContract.ets:
export interface VisitorDraft {
visitorName: string
contactPhone: string
visitPurpose: string
visitDate: string
}
export interface VisitReceipt {
receiptId: string
acceptedAt: string
status: string
}
export interface ApiEnvelope<T> {
code: string
message: string
data: T
}
export class VisitValidator {
static check(draft: VisitorDraft): string {
if (draft.visitorName.trim().length < 2) {
return '请填写至少两个字符的姓名'
}
if (!/^1[3-9]\d{9}$/.test(draft.contactPhone)) {
return '请核对联系电话'
}
if (draft.visitPurpose.trim().length === 0) {
return '请填写来访事由'
}
if (!/^\d{4}-\d{2}-\d{2}$/.test(draft.visitDate)) {
return '日期格式应为年-月-日'
}
return ''
}
}
字段校验不能止于“字符串不为空”。例如日期既要符合格式,还应在业务层确认日期是否可预约;联系电话的地域规则也要根据具体业务定义。上述检查只处理表单第一层输入问题,服务端仍需独立校验权限、时间范围和重复登记。页面可复用相同的错误文案,但不能以客户端结果替代服务端判定。
工程还可以把返回字段在服务端协议中写为固定枚举,例如 status=accepted、status=rejected,但客户端不要把业务状态和 HTTP 状态互相混淆。类型声明可以发现调用处拼写错误,却无法阻止服务端在运行时返回缺少字段的 JSON。对于回执等关键字段,必须补充判空和业务范围检查;对少量可选信息则以缺省值渲染。协议升级时先比较字段含义,再统一调整契约,而不是让不同页面各自通过类型断言绕过检查。
将 Axios 封装到唯一网络出口
把第三方依赖控制在 network/SubmissionClient.ets,后续更换实现时,页面只会感知业务方法。Axios 的 create、post 与 AxiosResponse 都有社区代码示例,采用 Promise 的返回方式可以在页面统一使用 async/await。请求头使用 JSON,并为每次访问设定合理的超时时间。
import axios, { AxiosInstance, AxiosResponse } from '@ohos/axios'
import { ApiEnvelope, VisitorDraft, VisitReceipt } from '../model/VisitContract'
export class SubmissionClient {
private client: AxiosInstance
constructor(baseURL: string) {
this.client = axios.create({
baseURL: baseURL,
timeout: 8000,
headers: { 'Content-Type': 'application/json' }
})
}
async submit(draft: VisitorDraft): Promise<VisitReceipt> {
const result: AxiosResponse<ApiEnvelope<VisitReceipt>> =
await this.client.post<ApiEnvelope<VisitReceipt>,
AxiosResponse<ApiEnvelope<VisitReceipt>>, VisitorDraft>(
'/v1/visits', draft
)
const body: ApiEnvelope<VisitReceipt> = result.data
if (body.code !== 'OK' || !body.data || !body.data.receiptId) {
throw new Error(body.message || '服务端拒绝了提交')
}
return body.data
}
}
泛型明确了请求体、HTTP 响应与业务载荷之间的关系。尤其要注意 HTTP 成功并不等于登记被接受:当服务端以 200 返回 code=INVALID_DATE 时,submit 必须按业务失败处理。另一方面,超时也不等于服务端没有保存;该区别直接决定下一篇离线队列要引入幂等键,而非盲目再次提交。

ArkUI 页面只管理输入和交互
页面收集输入并调用 VisitValidator,然后将业务结构交给 SubmissionClient。避免在 build 中发起网络请求,因为任何状态变化都可能引起组件重新构建。按钮通过 busy 控制重复点击,异常出口给出可操作的信息,而不是暴露底层异常字符串。
import { VisitorDraft, VisitValidator } from '../model/VisitContract'
import { SubmissionClient } from '../network/SubmissionClient'
@Entry
@Component
struct VisitFormPage {
@State visitorName: string = ''
@State contactPhone: string = ''
@State visitPurpose: string = ''
@State visitDate: string = '2026-11-03'
@State busy: boolean = false
@State feedback: string = ''
private api: SubmissionClient = new SubmissionClient('https://api.example.com')
private async submitForm(): Promise<void> {
if (this.busy) { return }
const draft: VisitorDraft = {
visitorName: this.visitorName.trim(),
contactPhone: this.contactPhone.trim(),
visitPurpose: this.visitPurpose.trim(),
visitDate: this.visitDate
}
const invalid: string = VisitValidator.check(draft)
if (invalid.length > 0) { this.feedback = invalid; return }
this.busy = true
this.feedback = '正在提交登记'
try {
const receipt = await this.api.submit(draft)
this.feedback = `登记已接受:${receipt.receiptId}`
} catch (err) {
this.feedback = '暂时无法确认登记结果,请查看登记记录'
} finally {
this.busy = false
}
}
build() {
Column({ space: 12 }) {
Text('访客登记').fontSize(24).fontWeight(FontWeight.Bold)
TextInput({ placeholder: '姓名', text: this.visitorName })
.onChange((value: string) => { this.visitorName = value })
TextInput({ placeholder: '联系电话', text: this.contactPhone })
.onChange((value: string) => { this.contactPhone = value })
TextInput({ placeholder: '来访事由', text: this.visitPurpose })
.onChange((value: string) => { this.visitPurpose = value })
TextInput({ placeholder: '到访日期', text: this.visitDate })
.onChange((value: string) => { this.visitDate = value })
Button(this.busy ? '提交中' : '提交登记')
.enabled(!this.busy)
.onClick(() => { this.submitForm() })
Text(this.feedback).fontSize(14)
}
.padding(20)
.width('100%')
}
}

这里使用普通文本输入来突出请求边界;真实预约业务可以将日期输入改为日期选择组件,并给出不可预约日期的禁用样式。通过 @State 更新反馈信息,错误不会被藏在控制台。按钮的不可点击状态也让用户明白当前正在处理,避免短时间内产生多个不同请求。
这一设计还有一个容易遗漏的细节:页面退出时不必为了隐藏加载标识而随意终止请求。对创建类操作,终止等待并不能撤销服务端已经写入的数据。可以在状态管理层为请求保存操作身份,页面返回后仍可根据回执列表查询结果;交互上把“退出页面”“取消本次登记”和“停止等待网络结果”区分成三个动作。只有服务端明确提供撤销接口时,业务取消才有独立的协议意义。
将网络错误归到明确的处理路径
网络错误可以分成连接失败、超时、HTTP 业务失败和响应格式异常。连接失败可提示检查网络;请求超时需要查询业务记录确认提交结果;响应结构改变应记录接口字段差异并由服务端修复,而不应让页面在未知数据上继续运行。对于包含联系电话的请求,调试日志记录接口路径、耗时和错误类别即可,避免输出完整表单、请求头中的凭证以及响应中的个人信息。
调试时按固定顺序观察:先检查网络权限和 HTTPS 证书,再确认请求方法、路径、JSON 字段是否与服务端契约一致;然后分别构造业务成功、业务拒绝、超时和缺少字段四种返回,核对页面反馈是否有差异。服务端应提供可查询的登记记录,让用户能够判断此前提交是否已被接受。只有把“已提交”“已被接受”和“结果未知”区分开,才能为后续离线保存创造可靠前提。
错误处理也应保证敏感字段不进入排查材料。网络层在捕获异常时可以记录接口路径、请求耗时、错误码与关联流水标识,但姓名、联系电话、授权令牌和表单正文都不适合作为公共日志内容。在开发环境中复核时,替换为经过脱敏的样本,并保留必要的错误类别即可;如需要追踪服务器处理结果,使用服务端签发的回执编号完成关联,能够同时减少隐私暴露和跨层依赖。
版本维护与后续扩展
@ohos/axios 的版本固定不等于永远无需升级。升级时要检查 OHPM 锁文件、包的更新记录、HarmonyOS SDK 兼容范围和实际使用的配置项;对移动网络、弱网超时与服务端错误码采用相同的回归用例。网络库负责发送与协议封装,业务层负责字段与操作语义,UI 负责交互反馈,这三个边界不能互相替代。
下一步在 VisitorDraft 之上引入具有固定标识的提交操作,即使网络中断或应用页面退出,也可以恢复排队中的登记,不会把一次用户操作错误地当成多次创建请求。
相关资料:华为开发者网络权限配置、华为开发者 ArkTS、https://gitee.com/openharmony-sig/ohos_axios/blob/master/README.md@ohos/axios 仓库与使用文档、版本更新记录。
更多推荐


所有评论(0)