昨天发了背单词小程序「优词记 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,列表接口普遍快了不少。
一点感受
这套请求层其实没什么黑科技,价值在于把约定固化到代码里:错误码语义、认证方式、参数格式,前后端一次对齐,之后新增接口双方都不用再沟通这些细节。对独立开发或小团队来说,这种「约定的复利」比任何单点优化都划算。
产品本体是个背单词小程序,教材同步 + 拼写/选词多模式练习 + 打卡日历,微信搜「优词记 Pro」可以直接体验。明天打算写写后端那条「全站唯一路由」的 Dispatcher 是怎么按约定分发请求的,感兴趣的可以关注一下。



网友评论 0