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 = 444
  const ERRCODE = 500

  let promiseQueue = []
  let exeQueue = false
  let needBeginLogin = true
  // 刷新token
  async 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根据自己实际情况调整

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023年全国青少信息素养大赛智能算法C++挑战赛复赛初中组真题,包含答案解析分享

【读前注意】:此卷是真题,答案解析辛苦整理,大家多多点赞并转发支持,需要下载空白文档题目版本(包含2023年小学组和初中组的题目pdf文件),可以在留言区的第一条留言的链接中进行复制,然后再浏览器中下载即可。 智能算法挑战复赛初中组 (总共

AngularJS基础语法(2009版本)

jquery和AngularJS 数据绑定和获取对比: jquery,要操作DOM: angularJS,无需操作DOM就可以进行动态数据变化: 要使用Angularjs就需要在html页面先引入: ng-app: html页面中,需要给…

操作系统的体系结构:宏内核和微内核

操作系统的体系结构是一个开放的问题。操作系统在核心态为应用程序提供公共的服务,那么操作系统在核心态应该提供什么服务、怎样提供服务?有关这个问题的回答形成了两种主要的体系结构:宏内核和微内核。 宏内核:大而全 宏内核系统…

【面试题-004】ArrayList 和 LinkList区别

ArrayList 和 LinkedList 都是 Java 中常用的动态数组实现,都实现了 List 接口,但它们在内部数据结构和性能方面有所不同: 内部数据结构: ArrayList 是基于动态数组的数据结构,它允许快速随机访问。数组的大小在创建时…

simCSE句子向量表示(1)-使用transformers API

SimCSE SimCSE: Simple Contrastive Learning of Sentence Embeddings. Gao, T., Yao, X., & Chen, D. (2021). SimCSE: Simple Contrastive Learning of Sentence Embeddings. arXiv preprint arXiv:2104.08821. 1、huggingface官网下载模型 官网手动下载:pri…

【Self-Attention——Transform—Bert】相关的基础理论

1.Self-Attention模型图解 传统的循环神经网络,如上左图1,并不能解决并行化的问题,右图就是一个self-Attention可以实现并行化,并且能解决对于所有信息的读取利用。 将self—Attention替换相应的GRU或者RNN,就能实现从…

C#WPF数字大屏项目实战09--机器产量统计

1、区域布局 2、柱状图 Live chart 是一个跨平台的图表库 .Net,这是一个简单、灵活、交互式、强大的跨平台图表库,支持Maui、Uno Platform、Blazor-wasm、WPF、WinForms、Xamarin、Avalonia、WinUI、UWP。提供超过60多种图表类型,包括&#…

NumPy应用(一)

NumPy学习篇1 NumPy是一个强大的Python库,它提供了高效的多维数组对象和各种用于数组操作的函数。以下是NumPy学习大纲,详细介绍了NumPy的核心功能和概念。 1. NumPy 简介 NumPy是一个用于处理多维数组的Python库,它提供了一个强大的数组对…

【启程Golang之旅】从结构到接口揭秘Go的“面向对象”面纱

欢迎来到Golang的世界!在当今快节奏的软件开发领域,选择一种高效、简洁的编程语言至关重要。而在这方面,Golang(又称Go)无疑是一个备受瞩目的选择。在本文中,带领您探索Golang的世界,一步步地了…

基于ssm校园自行车租赁系统-计算机毕业设计源码82064

摘 要 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,学校当然也不例外。基于ssm的校园自行车租赁系统是以实际运用为开发背景,运用软件工程原理和开发方法&#…

《已解决》F12显示已在程序中暂停

首先打开F12-->源代码 最后一步:

C#WPF数字大屏项目实战08--生产量/良品统计

1、区域划分 生产量/良品统计这部分位于第二列的第二行 2、livechart拆线图 定义折线图,如下: <lvc:CartesianChart> <lvc:CartesianChart.Series> <!--设置Series的类型为 Line 类型, 该类型提供了一些折线图的实现--> <lvc:LineSeries/>…

【安装】VMware虚拟机安装windows操作系统,VM的相关操作

目录 引出报错&#xff1a;press any key to boot form cd激活调整显示 在VMware上新建虚拟机&#xff0c;并安装Windows1、新建虚拟机2、装载 ISO 镜像3、安装Windows server 20164、开机初始化 虚拟机操作1、虚拟机基本操作2、虚拟机快照3、虚拟机克隆4、VMware Tools 总结 引…

vue-标签选择

效果 选中后 代码 <span :class"[item.bealtrue?p_yx_span span_active :span p_yx]" click"onTagSelect(index)" v-for"(item,index) in tagList" :key"index" >{{item.name}} </span> // 列表值 tagList:[ {id: 1, na…

设计模式(九)结构型模式---外观模式

文章目录 外观模式简介结构优缺点UML图具体实现UML图代码实现 外观模式简介 外观模式 &#xff08;Facade Pattern&#xff09;也叫门面模式&#xff0c;是一种通过为多个复杂的子系统提供一个一致的接口&#xff0c;而使这些子系统更加容易被访问的模式。MyBatis的Configurat…

Java利用POI绘制表格

前提需求 最近公司要求写一些记录的表格&#xff0c;并且带有导出功能。再深入学习后&#xff0c;表格的底层其实就是list遍历塞值&#xff0c;导出功能的话可以由前端&#xff0c;后端实现&#xff0c;但技多不压身嘛&#xff0c;这里我自己就写了后端的导出功能&#xff0c;…

【固定资产管理】软件系统建设方案体系文档(Word原件)

固定资产管理系统解决方案 1系统概述 1.1需求描述 1.2需求分析 1.3重难点分析 1.4重难点解决措施 2系统架构设计 2.1系统架构图 2.2关键技术 3系统功能设计 3.1功能清单列表 3.2资产采购 3.3资产验收 3.4资产入库 3.5资产领用 3.6资产出库 3.7资产维修 3.8资产…

【ARM-Linux篇】内核编译

一、Linux内核的主要功能 Linux内核的主要功能&#xff1a;进程管理、内存管理、驱动、系统调用 Linux操作系统框架 二、Linux内核编译流程 方法一&#xff1a; 1. 运行 build.sh 脚本&#xff0c; 记得加 sudo 权限 gyjgyj-virtual-machine:~/orangepi-build$ sudo ./buil…

如何跨渠道分析销售数据 - 7年制造业销售经验小结

如何跨渠道分析销售数据 - 7年制造业销售经验小结&#xff08;1&#xff09; 【前言】 在我过去7年销售工作生涯中&#xff0c;从第一年成为公司销冠后&#xff0c;我当时的确自满的一段时间&#xff0c;认为自己很了不起。但是第一年的销售业绩并没有拿到提成&#xff0c;最…

图解DSPy:Prompt的时代终结者?!

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba&#xff0c;xLSTM,KAN&#xff09;则提供了大模…