昨天发了背单词小程序「优词记 Pro」的整体架构复盘,有朋友对 uni-app 的 HTTP 层封装感兴趣,今天单独展开写一篇。

为什么不直接用 uni.request

uni.request 本身没问题,问题在于业务一多,每个请求都要重复处理这些事:拼 token、判断响应码、弹错误提示、登录失效跳转……散落在各个页面里,改一处规则要全局搜代码。

所以我在 shared/http/ 里封装了一个自研 HttpClient,核心思路就一个:拦截器链

拦截器链:Auth → Log → Response

请求发出前和响应回来后,依次经过三个拦截器:

Auth 拦截器:从 store 取 token,自动拼到 Authorization: Bearer <token> 请求头。页面代码里永远不需要关心认证。

Log 拦截器:开发环境打印完整请求/响应日志,线上静默。调试的时候不用到处塞 console.log

Response 拦截器:这是最核心的一层。后端所有接口统一返回 {error, data, message} 格式,error !== 0 即为异常,拦截器按错误码分流处理:

错误码 含义 自动行为
401 未登录 自动登出、跳转登录页
402 登录失效 弹窗提示重新登录
403 无权限 弹窗提示
406 异地登录 弹窗提示
500 服务器错误 弹窗提示 / throw

这样业务代码里拿到的永远是「已经处理过错误」的干净数据,页面层几乎见不到 try-catch 样板代码。需要自定义错误处理的场景(比如静默失败),通过配置项覆盖默认行为即可。

两个配套约定

1. POST/PUT 一律 JSON Body。早期踩过 form-data 和 JSON 混用的坑——同一个字段在不同接口里解析行为不一致。后来强制约定:所有写操作参数全部放 JSON Body,请求层统一设置 Content-Type,后端解析逻辑也简单了。

2. 移动端分页用 simplePage。无限滚动场景下用户根本不关心总页数,所以列表接口统一带 simplePage=1,后端跳过 count 查询,只返回当前页数据 + 有没有下一页。省一次全表 count,列表接口普遍快了不少。

一点感受

这套请求层其实没什么黑科技,价值在于把约定固化到代码里:错误码语义、认证方式、参数格式,前后端一次对齐,之后新增接口双方都不用再沟通这些细节。对独立开发或小团队来说,这种「约定的复利」比任何单点优化都划算。

产品本体是个背单词小程序,教材同步 + 拼写/选词多模式练习 + 打卡日历,明天打算写写后端那条「全站唯一路由」的 Dispatcher 是怎么按约定分发请求的,感兴趣的可以关注一下。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐