HarmonyOS7 HTTP 网络请求封装:统一拦截器实战

HarmonyOS7 HTTP 网络请求封装:统一拦截器实战
文章目录前言基础请求长啥样代码实现第一层统一 baseURL 和超时第二层请求拦截自动带 token核心代码第三层响应拦截统一错误处理完整示例业务里怎么用常见误区小白必踩完整可运行示例HTTP 请求封装代码解析写在最后前言几乎每个 app 都要联网。但如果你在每个页面里都写一遍httpRequest.request(...)、都手写错误处理、都手动拼 token代码会又臭又长改个 baseURL 要改二十处。正确做法封装一个统一的网络层。这篇文章我带你写一个带请求拦截自动加 token、响应拦截统一错误处理的 HTTP 封装以后业务里一行调用就完事。基础请求长啥样HarmonyOS 推荐用rcpRemote Communication Kit发请求比老http模块更现代。代码实现import{rcp}fromkit.RemoteCommunicationKitasyncfunctiongetUsers():PromiseUser[]{constsessionrcp.createSession()constrespawaitsession.get(https://api.example.com/users)returnresp.bodyasUser[]}这是最原始写法问题没有 baseURL、没有 token、没有统一错误提示。下面我们一层层包。第一层统一 baseURL 和超时constBASE_URLhttps://api.example.comclassHttp{privatesession:rcp.Sessionconstructor(){this.sessionrcp.createSession({baseAddress:BASE_URL,headers:{Content-Type:application/json}})}asyncgetT(path:string):PromiseT{constrespawaitthis.session.get(path)returnresp.bodyasT}}要点baseAddress设一次 baseURL后面只传/users这种相对路径。用泛型T让调用方拿到类型安全的返回不用自己 cast。第二层请求拦截自动带 token真实接口基本都要登录态。与其每个请求手写headers.token不如在封装里统一加核心代码asyncgetT(path:string):PromiseT{consttokenAppStorage.getstring(token)??constrespawaitthis.session.get(path,{headers:{Authorization:Bearer token}// 自动注入})returnthis.handle(resp)// 交给响应处理}AppStorage.get(token)是全局存的登录 token每次请求自动塞进 header。业务方完全不用管 token 从哪来。第三层响应拦截统一错误处理不同接口返回结构不同但成功/失败的判断逻辑是共通的。集中处理完整示例privatehandle(resp:rcp.Response):any{constcoderesp.statusCodeif(code200code300){returnresp.body// 成功返回数据}if(code401){// token 过期跳登录thrownewError(登录已过期请重新登录)}thrownewError(请求失败code)}2xx 才视为成功直接给业务数据。401 统一跳登录不用每个页面判断。其他错误抛异常调用方try/catch即可。业务里怎么用consthttpnewHttp()asyncloadData(){try{this.usersawaithttp.getUser[](/users)}catch(e){promptAction.showToast({message:(easError).message})}}业务代码干净得只剩取数据 出错提示两件事。这就是封装的价值重复的逻辑沉到底层业务只关心业务。常见误区小白必踩误区说明token 写死在业务代码里每处手写headers.token改一次要改二十处。交给封装层统一注入。不统一错误处理每个页面自己if (code401)重复又易漏。集中到响应拦截里。忘了await请求是异步的不await拿到的是 Promise 不是数据bug 极难查。下面这段代码可以直接复制到 DevEco Studio 里运行。建议你边读边敲改一改文末「动手改一改」里的参数亲眼看看效果。完整可运行示例HTTP 请求封装把http.createHttp()包一层统一处理 URL、错误、返回 JSON。代码解析// 一个最小可用的请求封装import{http}fromkit.NetworkKitasyncfunctiongetJSONT(url:string):PromiseT{constreqhttp.createHttp()try{constrespawaitreq.request(url,{method:http.RequestMethod.GET})if(resp.responseCode!200){thrownewError(HTTP resp.responseCode)}returnJSON.parse(resp.resultasstring)asT}finally{req.destroy()// 用完释放避免句柄泄漏}}// 使用EntryComponentstruct Page{Statetip:string加载中...aboutToAppear(){getJSON{title:string}(https://example.com/api).then((d){this.tipd.title}).catch((e){this.tip出错e.message})}build(){Column(){Text(this.tip)}.padding(20)}}你会看到什么进入页面自动发请求tip从「加载中」变成接口返回的数据若网络异常tip显示具体错误。动手改一改给getJSON增加第二个参数body支持 POST。在finally前加console.info打印耗时做基础性能观测。把tip初始值改成空加一个if (this.tip)条件渲染骨架屏。写在最后网络封装这套三层结构——baseURL、请求拦截加 token、响应拦截统错——是我每个项目的标配。它前期多花半小时后期省下的是成倍的维护成本。你现在就可以把项目里散落的httpRequest收拢到一个Http类里。等哪天要换域名、加签名、统一埋点你会感谢今天做了封装的自己。