uniapp项目中请求token超时处理

88 阅读1分钟

let env = require('./env.js'); // 在模块顶部添加全局状态管理 let isTokenRefreshing = false; // Token刷新中标记 let refreshSubscribers = []; // 重试请求队列 let isTokenExpiredGlobal = false; // 全局Token失效标记 /**

  • 网络请求 */ const request = (reqUrl, req) => { // 1. 全局失效检查 - 快速失败 if (isTokenExpiredGlobal) { return Promise.reject({ code: 'TOKEN_EXPIRED', message: 'Token已失效,请重新登录' }); }

    let token = uni.getStorageSync("token");

    // 2. 本地Token检查 if (!req.noAuth && !token) { console.log('req.noAuth===', req) redirectToLogin(); return Promise.reject('未登录'); }

    let reqParam = getConfigReqParam(reqUrl, req); if (token) { reqParam.header.Authorization = "Bearer " + token; }

    return new Promise((resolve, reject) => { uni.request({ url: reqParam.requestUrl, data: reqParam.data, header: reqParam.header, method: req.method, success: (res) => { const code = res.data.code; if (code === 'PR0000') { resolve(res.data); } else if (code === '401') { // Token失效 handleTokenExpiration(reqUrl, req, resolve, reject); } else { uni.showToast({ title: res.data.message || '请求错误' }); reject(res.data); } }, fail: (err) => { log.error('请求失败', err); reject(err); } }); }); };

// 使用示例(无需Token验证的登录接口): // post('xxx', { noAuth: true, data: { username, password } });

// Token失效处理中心 function handleTokenExpiration(reqUrl, req, resolve, reject) { // 1. 设置全局失效标记 isTokenExpiredGlobal = true;

// 2. 清除无效Token
uni.clearStorageSync();

// 3. 只执行一次跳转
if (!isTokenRefreshing) {
    redirectToLogin();
}

// 4. 将当前请求加入重试队列
refreshSubscribers.push(() => {
    request(reqUrl, req).then(resolve).catch(reject);
});

// 5. 延迟重置状态(避免重复跳转)
if (!isTokenRefreshing) {
    isTokenRefreshing = true;
    setTimeout(() => {
        isTokenRefreshing = false;
        isTokenExpiredGlobal = false;
        executeSubscribers();
    }, 1000); // 跳转动画完成时间
}

reject('登录状态已过期');

}

// 执行重试队列 function executeSubscribers() { refreshSubscribers.forEach(callback => callback()); refreshSubscribers = []; }

// 统一跳转方法 function redirectToLogin() { const pages = getCurrentPages(); if (pages.length && pages[pages.length-1].route === 'pages/login/login') { return; } uni.navigateTo({ url: '/pages/login/login', success: () => { console.log('已跳转至登录页'); } }); }

/**

  • 获取配置请求参数 */ function getConfigReqParam(url, req) { // 定义网络请求头 let header = { 'Content-Type': 'application/json', appid: 'sdr20250616' };

    let requestUrl = env.getBaseRequestURLV4() + url; let data = configReqParam(req.data ? req.data : req); return { requestUrl: requestUrl, header: header, data: data, }; }

/**

  • 配置请求信息 */ function configReqParam(data) { let param = data != undefined ? data : {}; //加入统一请求信息 return param; }

/**

  • 封装get请求函数 */ const get = (reqUrl, req) => { return request(reqUrl, { method: 'GET', ...req }); };

/**

  • 封装post请求函数 */ const post = (reqUrl, req) => { return request(reqUrl, { method: 'POST', ...req }); };

module.exports = { get, post };