• request.js
// request.js
import {getApptoken,getStoredApptoken
} from './tokenRequest' // 从合并模块导入// 全局配置
const MAX_RETRIES = 1 // 最大重试次数
const baseURL = 'https://your-api.com'// 请求队列和刷新状态
let requestsQueue = []
let isRefreshing = false// 核心请求函数
export const request = config => {return new Promise((resolve, reject) => {// 应用请求拦截器const processedConfig = requestInterceptor({baseURL,method: 'POST',needRefreshToken: true,retryCount: 0, // 记录重试次数...config})// 处理参数拼接(原URL有参数则用&,否则用?)const separator = processedConfig.url.includes('?') ? '&' : '?'const url = `${processedConfig.baseURL}${processedConfig.url}${separator}token=${processedConfig.apptoken || ''}`// 发起请求uni.request({...processedConfig,url,success: response => {// 应用响应拦截器responseInterceptor(response, processedConfig).then(resolvedData => resolve(resolvedData)).catch(err => reject(err))},fail: error => {console.error(`请求失败:${processedConfig.url}`, error)reject(error)}})})
}// 请求拦截器:统一处理请求前逻辑
const requestInterceptor = config => {config.header = {'Content-Type': 'application/json',...config.header}if (config.needRefreshToken) {const token = getStoredApptoken() // 使用合并模块的工具函数if (token) {config.token = token}}return config
}// 响应拦截器:统一处理响应后逻辑
const responseInterceptor = async (response, config) => {const {data,statusCode} = response// 处理成功响应if (statusCode === 200) {return data}// 处理401/400错误(token过期)if ((statusCode === 401 || statusCode === 400) && config.needRefreshToken) {// 检查是否超过最大重试次数if (config.retryCount >= MAX_RETRIES) {uni.showToast({title: '重试次数过多,请稍后再试',icon: 'none'})return Promise.reject(new Error('重试次数过多'))}// 如果正在刷新token,将请求加入队列等待if (isRefreshing) {return new Promise(resolve => {requestsQueue.push(() => resolve(request({...config,retryCount: config.retryCount + 1})))})}// 开始刷新tokenisRefreshing = truetry {// 获取新的tokenconst refreshSuccess = await getApptoken()if (!refreshSuccess) {return Promise.reject(new Error('获取新的token失败'))}// 重试原请求const retryResponse = await request({...config,retryCount: config.retryCount + 1})// 执行队列中所有挂起的请求requestsQueue.forEach(callback => callback())requestsQueue = []return retryResponse} catch (refreshError) {console.error('刷新token出错', refreshError)uni.showToast({title: '认证失败,请重新登录',icon: 'none'})return Promise.reject(refreshError)} finally {isRefreshing = false // 重置刷新状态}}// 其他错误处理return Promise.reject(new Error(`请求失败,状态码:${statusCode}`))
}// 封装常用请求方法
export const requestPost = (url, data, config = {}) => {return request({url,data,method: 'POST',...config})
}export const requestGet = (url, config = {}) => {return request({url,method: 'GET',...config})
}
  • tokenRequest.js
// tokenRequest.js// 应用配置
const infoObj = {appkey: process.env.ENV_TYPE === 'prod' ? 'C1A1140xxxxxxxxxxxxxxxxxxxxxxxxxxxx' :'3232313xxxxxxxxxxxxxxxxxxxxxxxxxxxx',appSecret: process.env.ENV_TYPE === 'prod' ? '34D7C4Exxxxxxxxxxxxxxxxxxxxxxxxxxxx' :'0A779D4xxxxxxxxxxxxxxxxxxxxxxxxxxxx',token: ''
}
const baseURL = 'https://your-api.com'// 基础请求(无拦截器)
const baseRequest = config => {return new Promise((resolve, reject) => {uni.request({method: 'GET',header: { 'Content-Type': 'application/json' },dataType: 'json',...config,success: response => resolve(response.data), // 直接返回datafail: error => reject(error)})})
}// 获取AppToken
export const getApptoken = () => {return new Promise((resolve, reject) => {const oldtoken = getStoredApptoken()const tokenUrl = `${baseURL}/getToken?token=${oldtoken}`baseRequest({ url: tokenUrl }).then(res => {if (res.token) {infoObj.token = res.tokenuni.setStorageSync('infoObj', JSON.stringify(infoObj))resolve(true)} else {uni.showToast({title: '更新token出错',icon: 'none'})resolve(false)}}).catch(err => {console.error('获取token接口失败', err)uni.showToast({title: '更新token接口出错',icon: 'none'})resolve(false)})})
}// 获取存储的AppToken
export const getStoredApptoken = () => {try {const stored = uni.getStorageSync('infoObj')return stored ? JSON.parse(stored).token : ''} catch (error) {console.error('获取存储的token失败', error)return ''}
}
  • xxx.vue
// 示例:调用POST接口(如需发送数据)
const submitData = async () => {try {const params = { name: 'test', age: 20 };// 调用POST接口(自动拼接token到URL)const res = await requestPost('/api/submit', params);console.log('提交成功', res);} catch (err) {console.error('提交失败', err);}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88709.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88709.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/88709.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL优化高手笔记

语雀完整版:https://www.yuque.com/g/mingrun/embiys/dv3btw/collaborator/join?tokenzMBwPzSMfSGINLuv&sourcedoc_collaborator# 《MySQL优化高手笔记》MySQL优化高手一、MySQL架构01 天天写CRUD,你知道你的系统是如何跟MySQL打交道的吗通过驱动连接数据库&am…

Git 详解:从概念,常用命令,版本回退到工作流

本文将从 Git 的核心概念讲起,详细介绍常用命令、各阶段版本回退、分支控制以及企业内常见的 Git 工作流。 Git 与 GitHub 简介 Git 简介 Git 是一个开源的分布式版本控制系统,由 Linus Torvalds 于 2005 年开发。它与集中式版本控制系统(…

CMSIS(Cortex Microcontroller Software Interface Standard)ARM公司为 Cortex-M 系列处理器

CMSIS(Cortex Microcontroller Software Interface Standard)是ARM公司为 Cortex-M 系列处理器(如 M0/M3/M4/M7/M23/M33 等)定义的一套硬件抽象层标准,旨在简化嵌入式开发,提高代码的可移植性和复用性。 核…

[特殊字符] 扫描式处理:Python 自动提取 PDF 中关键词相关表格并导出为 Excel

本文演示如何利用 pdfplumber 批量处理指定文件夹下 PDF 文档:定位关键词(如“主要会计数据”)出现的页码及下一页,提取其中的表格并保存为独立 Excel 文件。适用于财务报告、审计表格、统计报表等场景。 1️⃣ 第一步&#xff1a…

python3的返回值能返回多个吗?

在Python中,函数可以通过返回一个元组(tuple) 来间接实现返回多个值的效果。以下是具体说明: 实现方式:直接返回逗号分隔的值 Python会自动将这些值打包成一个元组: def multiple_return():a 1b "he…

UE5 Secondary Materials

首先放入材质A材质B放入Secondary Materials两个效果就能融合到一起了动态设置secondary material

AUTOSAR进阶图解==>AUTOSAR_SWS_FlashTest

AUTOSAR Flash Test模块详解与分析 基于AUTOSAR标准的Flash Test模块架构、功能与应用分析目录 1. Flash Test模块概述 1.1 模块作用与功能1.2 适用范围 2. Flash Test模块架构 2.1 模块位置2.2 组件关系 3. 状态管理 3.1 状态定义3.2 状态转换 4. 后台测试执行流程 4.1 测试间…

msf复现永恒之蓝

永恒之蓝(EternalBlue)是利用 Windows 系统的 SMB 协议漏洞(MS17-010)来获取系统最高权限的漏洞,利用 Metasploit 框架(MSF)复现该漏洞是一个复杂且具有一定风险的操作,必须在合法合…

格密码--LWE,DLWE和ss-LWE

格密码–LWE,DLWE和ss-LWE 0.数学符号数学符号含义备注Zq\mathbb{Z}_qZq​模qqq的整数集合,即{0,1,2,...,q−1}\{0,1,2,...,q-1\}{0,1,2,...,q−1}用于定义LWE、DLWE、ss-LWE等问题中矩阵和向量的元素取值范围,是基础整数环x∈RSx \in_R Sx∈…

【闭包】前端的“保护神”——闭包详解+底层原理

目录 一、闭包是什么?概念 二、闭包为什么存在?作用 1. 创建私有变量 2. 实现数据封装与信息隐藏 3. 模拟私有方法 4. 保存函数执行时的状态 5. 回调函数和事件处理 6. 模块化编程 7. 懒加载与延迟执行 三、闭包怎么用?实践业务场景 …

算法学习笔记:19.牛顿迭代法——从原理到实战,涵盖 LeetCode 与考研 408 例题

牛顿迭代法(Newtons Method)是一种强大的数值计算方法,由英国数学家艾萨克・牛顿提出。它通过不断迭代逼近方程的根,具有收敛速度快、适用范围广的特点,在科学计算、工程模拟、计算机图形学等领域有着广泛应用。牛顿迭…

小白学Python,操作文件和文件夹

目录 前言 一、操作文件路径 1.获取当前路径 2.创建文件夹 (1)mkdir()函数 (2)makedirs() 函数 3.拼接路径 4.跳转路径 5.判断相对路径和绝对路径 6.获取文件路径和文件名 二、操作文件和文件夹 1.查询文件大小 2.删除…

015_引用功能与信息溯源

引用功能与信息溯源 目录 引用功能概述支持的模型引用类型API使用方法引用格式应用场景最佳实践 引用功能概述 什么是引用功能 Claude的引用功能允许在回答基于文档的问题时提供详细的信息来源引用,帮助用户追踪和验证信息的准确性。这个功能特别适用于需要高可…

ROS2中的QoS(Quality of Service)详解

ROS2中的QoS(Quality of Service)详解1. 主要QoS参数2. 为什么需要设置QoS3. QoS兼容性规则4. 选择QoS策略的建议5. 调试QoS问题的方法6. 踩坑:订阅话题没有输出可能的原因:调试方法QoS是ROS2中用于控制通信质量和行为的机制。它定…

Cursor三大核心AI功能

一:Tab键:智能小助手 1.1 单行/多行代码补全 在代码中写出要实现的功能,第一次按Tab生成代码,第二次按Tab接受代码。1.2 智能代码重写 对已有代码重新编写。 写个注释告诉AI重构方法,然后鼠标点到方法内部,…

cesium添加原生MVT矢量瓦片方案

项目中需要基于cesium接入mvt格式的服务并支持属性拾取查询,通过一系列预研测试,最后选择cesium-mvt-imagery-provider开源插件完成,关键源码信息如下: npm i cesium cesium-mvt-imagery-provider //安装依赖包// 加载图层import…

AI金融风控:识别欺诈,量化风险的新利器

AI金融风控:识别欺诈,量化风险的新利器深度学习算法穿透海量交易数据,92.5%的不良贷款识别率宣告了金融风险防控新时代的来临。深圳桑达银络科技有限公司在2025年6月申请的“基于人工智能的金融交易反欺诈系统”专利,揭示了金融风…

【unitrix】 5.0 第二套类型级二进制数基本结构体(types2.rs)

一、源码 这是一个使用 Rust 类型系统实现类型级(type-level)二进制数的设计。 //! 类型级二进制数表示方案(第二套方案) //! //! 使用嵌套泛型结构体表示二进制数,支持整数和小数表示。use crate::sealed::Sealed;/// 类型级二进制数结构体 …

DAY01:【ML 第一弹】机器学习概述

一、三大概念 1.1 人工智能(AI) Artificial Intelligence 人工智能AI is the field that studies the synthesis and analysis of computational agents that act intelligently 1.2 机器学习(ML) Machine Learning 机器学习Fi…

AGX Xavier 搭建360环视教程【一、先确认方案】

设备默认自带 NVIDIA 硬件编解码能力(NVDEC/NVENC),但是需要你在 OpenCV 和 FFmpeg 里正确启用 调通 GStreamer 或 nvmpi,才真正能用起来!这里的硬解码是核心:Jetson 平台的硬解码,要么走 GStr…