网站建设板块今天的新闻主要内容
在 uni-app 中封装一个全局通用的 ajax 请求函数,支持 Promise,使用 uni.request() 进行请求,并且具备 自动刷新 token 的功能。以下是详细步骤:
实现步骤
- 创建
request.js统一封装ajax请求 - 管理
token(存储、获取、刷新) - 处理
401(登录过期)自动刷新token - 防止
token过期时多个请求同时触发refresh_token - 错误处理和
Promise封装
完整代码
创建 utils/request.js 作为 uni.request 的封装:
utils/request.js
// 导入 uni-app 的 storage API
const BASE_URL = 'https://api.example.com'; // 你的后端接口地址let isRefreshing = false; // 是否正在刷新 token
let refreshSubscribers = []; // 存储刷新 token 期间的请求/*** 刷新 token 并返回新的 token*/
function refreshToken() {if (isRefreshing) {// 如果已经在刷新 token,则返回一个等待的 Promisereturn new Promise((resolve) => {refreshSubscribers.push(resolve);});}isRefreshing = true;return new Promise((resolve, reject) => {uni.request({url: `${BASE_URL}/auth/refresh`, // 刷新 token 的 APImethod: 'POST',header: {'Authorization': `Bearer ${uni.getStorageSync('refreshToken')}` // 发送 refreshToken},success: (res) => {if (res.data.code === 200) {const newToken = res.data.data.token;const newRefreshToken = res.data.data.refreshToken;// 存储新的 token 和 refreshTokenuni.setStorageSync('token', newToken);uni.setStorageSync('refreshToken', newRefreshToken);// 让所有等待的请求继续refreshSubscribers.forEach((callback) => callback(newToken));refreshSubscribers = [];resolve(newToken);} else {reject('Refresh Token Failed');}},fail: (err) => reject(err),complete: () => {isRefreshing = false;}});});
}/*** 统一请求封装* @param {Object} options* @param {String} options.url 请求地址(不含 BASE_URL)* @param {String} [options.method='GET'] 请求方法* @param {Object} [options.data={}] 请求参数* @param {Object} [options.header={}] 请求头* @param {Boolean} [options.auth=true] 是否需要携带 token*/
function request({ url, method = 'GET', data = {}, header = {}, auth = true }) {return new Promise((resolve, reject) => {// 获取存储的 tokenlet token = uni.getStorageSync('token');// 组装请求头let finalHeader = {'Content-Type': 'application/json',...header};if (auth && token) {finalHeader['Authorization'] = `Bearer ${token}`;}uni.request({url: `${BASE_URL}${url}`,method,data,header: finalHeader,success: async (res) => {if (res.statusCode === 200) {resolve(res.data);} else if (res.statusCode === 401 && auth) {// token 失效,自动刷新 tokentry {const newToken = await refreshToken();finalHeader['Authorization'] = `Bearer ${newToken}`;// 重新发起请求uni.request({url: `${BASE_URL}${url}`,method,data,header: finalHeader,success: (retryRes) => resolve(retryRes.data),fail: (retryErr) => reject(retryErr)});} catch (error) {reject('登录状态失效,请重新登录');uni.removeStorageSync('token');uni.removeStorageSync('refreshToken');uni.reLaunch({ url: '/pages/login/login' });}} else {reject(res.data);}},fail: (err) => {reject(err);}});});
}export default request;
使用方式
在 pages/index/index.vue 页面调用封装的 request.js:
import request from '../../utils/request.js';request({url: '/user/info',method: 'GET'
}).then(res => {console.log('用户信息:', res);
}).catch(err => {console.error('请求失败:', err);
});
核心功能解读
- 支持
Promise,简化then/catch处理 - 全局
request统一封装,避免每个请求都写uni.request - 自动携带
token,401 过期自动刷新 - 防止多个请求同时触发
refreshToken,队列处理 - 若
refresh_token失效,清除token并跳转到login页面
优化建议
- 错误信息细化:根据后端
code细分错误(如403、500)。 - 可配置
BASE_URL:放到config.js,区分dev和prod环境。 - 超时处理:可加
setTimeout限制请求时间。
这样,uni-app 就具备了全局 ajax 请求封装,且能自动刷新 token,提升开发效率! 🚀
