uniapp登录成功后跳回原有页面+无感刷新token

uniapp登录成功后跳回原有页面

引言

在C端的页面场景中,我们经常会有几种情况到登录页:

  • 区分需要登录和不用登录的页面,点击需要登录才能查看的页面
  • 已经登录但是超时,用户凭证失效等原因

以上情况可以细分为两种,一种是从未登录过的,需要第一次去登录,还一种是已经登录了,但是cookie失效了,需要重新获取用户凭证,这样的话后端会将两个状态码区分,那我们前端需要根据不同的状态码进行相应的处理。

第一次登录时

当用户从未登录时,我们需要跳到登录页去登录后再返回到原有页面,这样才是正常的交互逻辑。

  1. 第一步需要先保存当前路由
// 记录路由地址
const fungoPreviousPage = () => {let routes = getCurrentPages(); // 获取当前打开过的页面路由数组let curRoute = routes[routes.length - 1].route //获取当前页面路由let curParam = routes[routes.length - 1].options; //获取路由参数// 拼接参数let param = ''for (let key in curParam) {if (!param) {param += key + '=' + curParam[key]} else {param += '&' + key + '=' + curParam[key]}}uni.setStorageSync('pageUrl', param ? `/${curRoute}?${param}` : `/${curRoute}`)
}
  1. 登录成功后判断是否有pageUrl,有就说明回到原页面
   var pageUrl = uni.getStorageSync('pageUrl')if (pageUrl) {// 如果为tabbar页面则用reLaunch跳转if (['/pages/home/index'].includes(pageUrl)) {uni.reLaunch({url: pageUrl})} else {uni.redirectTo({url: pageUrl})}//跳转后,删除url记录避免重复跳转uni.removeStorageSync('pageUrl')} else {// 如果没有默认跳转到首页uni.reLaunch({url: '/pages/home/index'})}
  1. 回到原页面后点击返回需要返回到上一层页面(排除登录页)

    这点要注意的是整个流程是首页-a-登录页-a,如果在a页面点击返回时是要到首页,则需要注意以下

    a页面跳转到登录页时需要使用uni.redirectTo跳转,登录页跳转到a页面也需要使用uni.redirectTo

    在这里插入图片描述

cookie失效

cookie失效了需要无感知更新cookie,这个时候需要先将请求的队列存起来,等刷新cookie再去调用原来的接口就行。

后端一般会在登录成功后返回两个token值,一个用来校验用户信息,一个用来获取新的token,我这边分为token和access_token两个字段,其实就一个时效长一个时效短。

完整代码如下

  let devUrl = '';import store from '../store/index.js'import { loginOut } from './index.js'const baseUrl = devUrl;const POST = 'POST';const UPLOAD = 'UPLOAD';const SUCCESS_CODES = 200;const RefreshCode = 777;const LogoutCode = 503;const TOKEN_ERROR = 444const ERRCODE = 500let promiseQueue = []let exeQueue = falselet needBeginLogin = true// 刷新tokenasync function RefreshTokenRQ(cb) {try {if (store.state.access_token) {uni.request({url: `${baseUrl}/user/refreshToken`,data: {exchangeToken: store.state.access_token},success(res) {if (res.data.status === SUCCESS_CODES) {store.commit('setToken', res.data.data)cb && cb()} else {loginOut()}}})} else {loginOut()}} catch (e) {}}const getHeader = () => {return {token: store.state.token,};};/**** @param {string} method 请求方法* @param {string} url api地址* @param {string} data 入参*/const request = async (requestObj) => {// 显示加载中 效果// uni.showLoading({// 	title: "",// 	mask: true,// });return new Promise((resolve, reject) => {uni.request({url: `${baseUrl}${requestObj.url}`,method: requestObj.method || 'get',data: requestObj.data || {},header: Object.assign(getHeader(), requestObj.header || {}),success(res) {// 请求成功const data = res.data;requestMethods(requestObj, data, resolve, reject )},fail(err) {console.log(err);// 请求失败reject(new Error('Por favor verifique a rede'));}});})}function requestMethods (requestObj, data, resolve, reject) {if (data.status === SUCCESS_CODES) {if (requestObj.resolve) {requestObj.resolve(data.data);let promiseQueueItem = promiseQueue.shift();if (exeQueue) {exeQueue = false;while (promiseQueueItem) {request(promiseQueueItem);promiseQueueItem = promiseQueue.shift();promiseQueue = promiseQueue;}if (!promiseQueueItem) {exeQueue = true;needBeginLogin = true;}}} else {resolve(data.data);}} else {// 其他异常if (data.status === RefreshCode) {try {if (store.state.access_token) {requestObj.resolve = resolve;promiseQueue.push(requestObj); //请求失败了,把该请求放到promise队列,等待更新token后重新调用。if (!needBeginLogin) {return;}//防止重复刷新token。needBeginLogin = false;RefreshTokenRQ(() => { //获取完token以后执行回调//重新登陆以后调用一次队列中的promise;并设置队列为可循环状态。let promiseQueueItem = promiseQueue.shift();if (promiseQueueItem) {exeQueue = true;request(promiseQueueItem);}}, true)} else {loginOut()}} catch (e) {}return} else if (data.status === LogoutCode || data.status === TOKEN_ERROR) {loginOut()return;} else {uni.showToast({title: data.message,icon: 'none'});}reject(data);}}export function get(url, data, header = {}, method = 'GET') {return request({url,data,header})}export function post(url, data, header = {}, method = 'POST') {return request({url,data,method,header})}export default{get,post};

以上loginOut和store根据自己实际情况调整

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

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

相关文章

单片机/嵌入式小白教程—硬件(三)51单片机最小系统

目录 简介 51单片机器件原理图 复位电路 供电电路 晶振电路 下载电路 最小系统原理图 更加方便的51单片机 简介 传统51单片机最小系统包含:复位电路、供电电路、晶振电路、下载电路 51单片机器件原理图 其中, 第9脚(RST)…

DOM型XSS

前言 什么是DOM型XSS DOM型XSS漏洞是一种特殊类型的XSS,是基于文档对象模型 Document Object Model (DOM)的一种漏洞。 什么是DOM DOM全称Document Object Model,是一个与平台、编程语言无关的接口,它允许程序或脚本动态地访问和更新文档内容、结构和样式&#xff0…

橙派探险记:开箱香橙派 AIpro 与疲劳驾驶检测的奇幻之旅

目录 引子:神秘包裹的到来 第一章:香橙派AIpro初体验 资源与性能介绍 系统烧录 Linux 镜像(TF 卡) 调试模式 登录模式 第二章:大胆的项目构想 系统架构设计 香橙派 AIpro 在项目中的重要作用 第三章&#xf…

[Redis]String类型

基本命令 set命令 将 string 类型的 value 设置到 key 中。如果 key 之前存在,则覆盖,无论原来的数据类型是什么。之前关于此 key 的 TTL 也全部失效。 set key value [expiration EX seconds|PX milliseconds] [NX|XX] 选项[EX|PX] EX seconds⸺使用…

苏州金龙新V系客车科技助力“粤”动广州

粤动活力新V系! 5月23日,苏州金龙新V系智慧客车推介会在羊城广州举行。活动现场展出了4款新V系代表车型,来自广东省旅游客运、道路运输行业的200余位从业者齐聚一堂,共同品鉴、体验了苏州金龙新V系产品的“新、心、芯”魅力。苏州…

如何降本增效获得目标客户?AI企业使用联盟营销这个方法就对了!

AI工具市场正在迅速发展,现仍有不少企业陆续涌出,那么如何让你的工具受到目标群体的关注呢?这相比是AI工具营销人员一直在思考的问题。 为什么AI企业难以获客呢? 即使这个市场正蓬勃发展,也无法保证营销就能轻易成功…

英语学习笔记29——Come in, Amy!

Come in, Amy! 进来,艾米! shut v. 关严 区别:shut the door 把门关紧 口语:Shut up! 闭嘴!    态度强硬,不礼貌 例句:请不要把门关严。    Don’t shut the door, please. bedroom n. …

STM32-12-OLED模块

STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 文章目录 1. OLED显示屏介绍2. OLED驱动原理3. OLED驱动芯片简介4…

一年收入大几十个的副业兼职,闲鱼新玩法,新手小白可做,无门槛

在开始分享之前,我想先了解一下,大家是否曾在各大公众号上参与过各种打卡活动?比如减肥打卡、英语阅读打卡、考研考公打卡等等。如今,打卡已经成为现代人生活中不可或缺的一部分。无论是学习、健身还是工作,打卡都能有…

MGR集群模拟故障切换

说明: 1、MGR集群搭建起来,但不知道是否能进行启动切换,故要手动模拟故障并且验证 2、停止主库master服务,登录mysql查看MGR是否进行自动切换。 3、主库切换完成以后,手动将宕机的服务器添加到MGR集群中。 一、模拟故障…

2024年3月电子学会青少年软件编程 中小学生Python编程等级考试一级真题解析(选择题)

2024年3月Python编程等级考试一级真题解析 选择题(共25题,每题2分,共50分) 1、下列哪个命令,可以将2024转换成2024呢 A、str(2024) B、int(2024) C、float(2024) D、bool(2024) 答案:A 考点分析&…

C#解析JSON的常用库--Newtonsoft.Json

一、库介绍 在C#中,解析JSON的常用库有Newtonsoft.Json(也称为Json.NET)和 System.Text.Json(从 .NET Core 3.0 开始引入)。本文主要介绍 Newtonsoft.Json。 二、下载 官网: https://www.nuget.org/pack…

使用 retrievers 在 Elasticsearch 中进行语义重新排序

作者:来自 Elastic Adam Demjen, Nick Chow 什么是语义重新排序? 语义重新排序(semantic reranking)是一种方法,它允许我们利用快速检索方法的速度和效率,同时在其上分层语义搜索。它还允许我们立即将语义…

【Python】解决Python报错:TypeError: %d format: a number is required, not str

🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

STM32定时器及输出PWM完成呼吸灯

文章目录 一、STM32定时器原理1、基本定时器2、通用定时器(1)时钟源(2)预分频器PSC(3)计数器CNT(4)自动装载寄存器ARR 3、高级定时器 二、PWM工作原理三、控制LED以2s的频率周期性地…

CyberDAO M级共识交流会·西安站圆满落幕:共筑Web3美好未来

CyberDAO M级共识交流会于2024年5月28日在西安隆重举行,这是一场CyberDAO精英汇聚的盛会,以同心共筑,志在必达为主题口号与DAO精英携手并进,共筑CyberDAO美好宏图。CyberDAO的使命是降低WEB3的门槛,帮助用户轻松抓住行…

【微服务】springboot 构建docker镜像多模式使用详解

目录 一、前言 二、微服务常用的镜像构建方案 3.1 使用Dockerfile 3.2 使用docker plugin插件 3.3 使用docker compose 编排文件 三、环境准备 3.1 服务器 3.2 安装JDK环境 3.2.1 创建目录 3.2.2 下载安装包 3.2.3 配置环境变量 2.2.4 查看java版本 3.3 安装maven …

JVM学习-垃圾回收(二)

标记-清除(Mark-Sweep)算法 当堆中的有效内存空间被耗尽的时候,就会停止整个程序(stop the world),然后进行两项工作,第一项则是标记,第二项是清除 标记:Collector从引用根节点开始遍历,标记所有被引用的…

深入理解哈希加密:md5在保护用户数据中的应用

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、md5加密方法简介 二、md5加密方法的实现 示例代码: 三、md5加密方法在实际…

老师如何对付挑事儿的家长?

身为老师,你有没有遇到过这样的家长:孩子在学校里闹点小矛盾,或者作业分数有点争议,他们就气势汹汹地来找你,说你偏心,甚至在其他家长面前说三道四?面对这种爱“挑事”的家长,老师们…