今天我们就来聊聊 Uni-app 项目的底层基石------网络请求(Request)的深度封装。
在实际开发中,直接在页面里写 uni.request 是大忌。如果接口有一百个,当你需要统一在 Header 加一个 token 或者处理登录过期时,你会写到崩溃。
🚀 今日份:企业级 Request 请求层封装
一个优秀的请求封装应该解决三个核心问题:统一配置、拦截器处理、异常监控。
💡 核心逻辑:拦截器(Interceptor)
Uni-app 提供了 uni.addInterceptor,但更灵活的做法是基于 Promise 自己封装一个类。
📝 实战:高扩展性的请求类封装
我们可以创建一个 request.js:
javascript
// 基础配置
const BASE_URL = 'https://api.example.com';
export const request = (options) => {
return new Promise((resolve, reject) => {
// 1. 请求拦截:注入 Token
const token = uni.getStorageSync('token');
const header = {
'Content-Type': 'application/json',
...options.header
};
if (token) header['Authorization'] = `Bearer ${token}`;
uni.request({
url: BASE_URL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: header,
timeout: 10000,
success: (res) => {
// 2. 响应拦截:统一处理状态码
const { statusCode, data } = res;
if (statusCode === 200) {
if (data.code === 200) {
resolve(data.data); // 只返回业务数据
} else if (data.code === 401) {
// Token 失效,跳转登录
uni.navigateTo({ url: '/pages/login/login' });
reject(data);
} else {
uni.showToast({ title: data.msg || '业务错误', icon: 'none' });
reject(data);
}
} else {
uni.showToast({ title: `网络错误: ${statusCode}`, icon: 'none' });
reject(res);
}
},
fail: (err) => {
uni.showToast({ title: '连接服务器失败', icon: 'none' });
reject(err);
}
});
});
};
🛠️ 进阶:如何优雅地调用?
不要在页面里直接引用 request.js,建议建立一个 api 模块:
api/user.js
javascript
import { request } from './request.js';
export const login = (data) => request({ url: '/auth/login', method: 'POST', data });
export const getUserInfo = () => request({ url: '/user/info' });
pages/index.vue
javascript
import { getUserInfo } from '@/api/user.js';
async onLoad() {
try {
const info = await getUserInfo();
this.userInfo = info;
} catch (e) {
// 错误已在封装层统一弹窗,这里处理特定逻辑即可
}
}
⚠️ 避坑指南:小程序端的并发限制
- 并发限制 :微信小程序同域名下的并发请求不能超过 10个。如果页面初始化瞬间发出 15 个请求,后 5 个会报错。
- 对策:合并接口,或者在封装层实现一个"请求队列"。
- HTTPS:小程序生产环境必须使用 HTTPS,且要在后台配置域名白名单。
- 大文件上传 :上传文件不要用
uni.request,必须使用uni.uploadFile,它的封装逻辑与普通请求类似,但拦截器处理略有不同。
💡 核心总结
- 剥离 BaseURL:方便一键切换开发版、测试版、生产版。
- 响应拦截器:是处理"登录失效"最优雅的地方。
- Promise 化 :配合
async/await使用,让异步代码像同步一样整洁。