HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)

发布时间:2026/8/7 22:47:12
HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四) 系列文章目录HarmonyOS Next 系列之省市区弹窗选择器实现一HarmonyOS Next 系列之验证码输入组件实现二HarmonyOS Next 系列之底部标签栏TabBar实现三HarmonyOS Next 系列之HTTP请求封装和Token持久化存储四HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现五HarmonyOS Next 系列之可移动悬浮按钮实现六HarmonyOS Next 系列之沉浸式状态实现的多种方式七HarmonyOS Next系列之Echarts图表组件折线图、柱状图、饼图等)实现八HarmonyOS Next系列之地图组件Map Kit使用九HarmonyOS Next系列之半圆环进度条实现十HarmonyOS Next 系列之列表下拉刷新和触底加载更多数据实现十一HarmonyOS Next系列之实现一个左右露出中间大两边小带缩放动画的轮播图十二文章目录系列文章目录前言一、实现设计二、代码实现1.http请求工具类request.ets2.token持久化存取3.页面使用前言HarmonyOS Next基于API11封装一个http请求工具类自动拦截token失效跳转登录页以及token持久化存取方案。一、实现设计对于接口请求我们最关心两个东西一个是请求参数另一个是接收服务器返回的数据1请求参数最常设置的有请求链接url、请求方式methodpost,get等、请求参数data、请求数据类型Content-Type、登录凭证token其中token可从本地持久化读取无需传入剩下四个可设计为动态传参//接口入参数据类型interfaceRequestParams{url:string//请求链接method?:http.RequestMethod//请求方式data?:Object//请求额外数据headerContentType?:string//请求数据类型}2返回数据一般是个对象 常见固定字段有code:状态码 message:接口响应说明 data:返回数据故接口返回数据类型可定义为//接口请求返回数据类型interfaceResponseResult{code:number//状态码message:string//处理信息data:Object|null//返回数据}ps:根据实际需要也可按需添加字段对于返回数据code状态码一般定义1、200为请求成功2、401 token失效无效或缺失3、其他情况归为请求失败所以对于接口返回数据可根据code值分三种情况处理例如if(code200){//请求成功//返回数据}elseif(code401){//token失效//拦截跳转到登录页router.replaceUrl({url:/pages/login})}else{//请求失败}ps:当然状态码也可根据实际定义修改Token持久化存储为了配合登录方案实现方便在EntryAbility使用token我们这里选择了Preferences作为存储方案。最后熟悉web开发的同学都知道web项目中习惯把接口定义放置在api文件夹下统一管理然后在页面引入使用再此沿用该开发习惯方便后期维护。二、代码实现目录结构1.http请求工具类request.ets封装一个http请求工具类文件默认导出一个请求函数返回Promise(接口返回数据)utils/request.etsimporthttpfromohos.net.http;import{BusinessError}fromohos.base;importpromptActionfromohos.promptActionimport{getToken}from./indeximportrouterfromohos.router;//baseURL接口域名constBASEURL:stringhttps://xxxxxxx.com//登录页路由constLOGINPAGEURLpages/common/login//接口入参数据接口interfaceRequestParams{url:string method?:http.RequestMethod data?:Object headerContentType?:string}//接口请求返回数据类classResponseResult{code:number//状态码message:string//处理信息data:Object|null//返回数据constructor(code?:number,message?:string,data?:Object|null|undefined){this.codecode??0this.messagemessage??this.datadata??null}}/** * * param params:接口请求参数object类型 * { * url :请求连接 * method 请求方法 * data 请求数据 * headerContentType 请求头发送的数据格式 * } * returns PromiseResponseResult */exportdefaultfunctionrequest(params:RequestParams):PromiseResponseResult{returnnewPromise(async(resolve:(res:ResponseResult)void,reject:(res:ResponseResult|string|BusinessError|http.HttpResponse)void){//请求头contentTypeletcontentType:stringparams.headerContentType||application/json//默认提交数据类型为application/json//请求数据dataletrequestData:Object|undefinedparams.data;//application/x-www-form-urlencoded类型参数处理成keyvalue形式if(contentTypeapplication/x-www-form-urlencoded){if(typeofparams.dataobject){requestDataObject.entries(requestDataasobject).reduce((prev:string,cur:ArrayObject){return(prev${prev})${cur[0]}${cur[1]}},)}}//从本地存储获取tokenlettoken:stringawaitgetToken()lethttpRequesthttp.createHttp();httpRequest.request(BASEURLparams.url,{method:params.method??http.RequestMethod.GET,//默认get方法header:{Content-Type:contentType,token},extraData:requestData,readTimeout:30000,connectTimeout:30000},(err:BusinessError,data:http.HttpResponse){if(!err){//请求成功if(data.responseCode200){letres:ResponseResultJSON.parse(${data.result});letresponsenewResponseResult(res.code,res.message,res.data)//状态码code200表示请求成功,状态码可根据实际接口文档修改if(res.code200){resolve(response);}//状态码code401表示token失效,状态码可根据实际接口文档修改elseif(res.code401){//跳转登录页router.clear()//清空历史页面//跳转到登录页router.replaceUrl({url:LOGINPAGEURL})}//其他情况接口异常else{showToast(response.message)reject(response);}}//请求失败else{showToast()reject(data)}}//请求失败else{showToast(err.message)reject(err)}// 取消订阅HTTP响应头事件httpRequest.off(headersReceive);// 当该请求使用完毕时主动销毁该JavaScript Object。httpRequest.destroy();})})}//弹窗提示constshowToast(message?:string){promptAction.showToast({message:message||请求出错,duration:2000})}说明1定义了接口前缀域名端口号?通用匹配符 BASEURL可根据实际修改2定义了登录页面路由 LOGINPAGEURL token失效跳转使用可根据实际修改3函数request入参是个对象包含如下属性{url:请求连接 method?请求方法 data?请求数据 headerContentType?请求头发送的数据格式}method不传默认get方式headerContentType 不传默认application/json当contetn-type为 “application/x-www-form-urlencoded” data请求参数 自动处理成keyvalue形式4请求结果返回Promise{code:number//状态码message:string//处理信息data:Object|null//返回数据}当code200promise返回接口数据当code401 token失效自动跳转登录页当code其他值表示请求失败showToast显示接口message字段文字5请求头默认添加token数据从本地存储读取2.token持久化存取1entryability/EntryAbility.etsimportdataPreferencesfromohos.data.preferences;............onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{globalThis.getPreferences(){letpreferences:PromisedataPreferences.PreferencesdataPreferences.getPreferences(this.context,appStore)returnpreferences}}EntryAbility. onCreate周期函数内给全局变量globalThis添加getPreferences 属性方法方便快速获取Preferences实例 添加到globalThis是为了后续页面开发或者工具类使用Preferences2utils/index.ets 工具类importdataPreferencesfromohos.data.preferences;//获取tokenexportconstgetToken:Functionasync(){try{letpreferences:dataPreferences.PreferencesawaitglobalThis.getPreferences()returnpreferences.getSync(token,)}catch(e){}return}//设置token并本地持久化存储exportconstsetToken:Functionasync(value:string){try{letpreferences:dataPreferences.PreferencesawaitglobalThis.getPreferences()preferences.putSync(token,encodeURIComponent(value))awaitpreferences.flush()}catch(e){console.log(JSON.stringify(e),e)}}在工具类index.ets封装2个方法getTokensetToken分别为获取token值和设置token值其中setToken在登录成功获取到token值时候调用存入本地持久化3.页面使用新建api文件夹、新建与页面同名的ets文件写入api定义api/home.etsimporthttpfromohos.net.httpimportrequestfrom../utils/requestclassparams{storeId:string}//获取首页数据exportfunctiongetHomeData(data:params){returnrequest({url:/api/store/home,method:http.RequestMethod.POST,//不传默认GETdata,headerContentType:application/x-www-form-urlencoded//不传默认application/json})}//其他接口exportfunctionxxxxx(data:params){returnrequest({url:xxxxxxxx,data,})}..................页面引入pages/Home.etsimport{getHomeData}from../api/homeEntry Component struct Home{aboutToAppear():void{getHomeData({storeId:17815455885}).then(res{console.log(JSON.stringify(res),接口返回数据)}}}运行结果