写一个解决思路

需要做单点登录,请求的时候要知道响应的数据是否是401已经过期,来进行退出登录的操作

方案1-给每个Ajax增加拦截器

既然要监听返回的数据,那就简单的就是在ajax增加一个响应拦截器

每个ajax长得都差不多

js 复制代码
$.ajax({
        type: 'post',
        data: param,
        url: 'query',
        dataType: 'json',
        success: function (res) {
           
        },
       
    })

但是因为项目老旧的原因,没有对其进行一个封装,导致每个ajax的请求都是单独的请求

也就是说,如果要对ajax进行拦截,那么我可能需要改动成百上千个地方

也不多,只有六百多个地方需要改动

我不是人啊?我不是人啊?我不是人啊? 下一个

方案2-封装Ajax

在第一个的基础上,拦截器是必不可少的,所以要用拦截器的话,就需要统一把Ajax封装起来

普通的ajax,因为每个ajax都是这格式,大家带的参数不同,可能多也可能少

js 复制代码
$.ajax({
    type: 'post',
    data: param,
    url: 'query',
    dataType: 'json',
    success: function (res) {
    },
})

加了拦截器的ajax,也就是我要封装之后的请求的样例

js 复制代码
$.ajax({
        url: options.url,
        data: options.param,
        type: "post",
        dataType: "json",
        success: function (data) {
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
        },
        beforeSend: function () {//请求拦截
            if (options.displayLoading) {

            }
        },
        complete: function () {//响应拦截
            if (options.displayLoading) {

            }
        }
    });

那要怎么封装比较方便,不就是多了参数,暴力一点好了

js 复制代码
function commonAjax(opt){
    $.ajax({
        ...opt,
        beforeSend: function () {
            if (options.displayLoading) {

            }
        },
        complete: function () {
            if (options.displayLoading) {

            }
        }
    });
}

相当于是把ajax套多一层,给每一层增加一套拦截器,但还是要同时修改几百个地方,去修改

$.ajax 改成 allAjax

批量改变,并且格式不用变,也算是一种好方案,但我偏偏不干,我撤回,头脑发热,直接这么写

js 复制代码
$.ajax= $.ajax({
    ...opt,
    beforeSend: function () {
        if (options.displayLoading) {

        }
    },
    complete: function () {
        if (options.displayLoading) {

        }
    }
});

不记得是不是差不多这样写了,直接来个死循环,这个pass,还是老老实实去改

遇到问题

ajax用到的地方是在太多了,以至于我的commonAjax不知道放到哪个地方,

$.ajax依靠jquery,那肯定必须放到jqeury的后面,但是ajax请求体获取参数的时候,又需要用到封装的util,也需要用到util的后面,但出于某个bug,jquery不放到最后就会报错,又出现了其他undefined的问题,奇奇怪怪,思考了一会之后,这六百多个改动,不知道后面还会又什么神奇的问题,因而放弃该方案。

方案3-拦截一个必调的接口

不就是判断接口时候401嘛,那意思就是每个接口请求都会401,那么我不用每个接口都去做拦截,我只给某个接口做拦截

但是必须保证这接口刷新页面的时候会调用,这里有经验的很明显知道用户信息或者菜单信息的接口刷新页面的时候会调用,那么就需要在地方做拦截,拦截到401的时候,返回登录页面。

但是并不完美,单点登录如果不刷新页面,那用户点击其他页面,仍然是没有反应

比如此时接口已经401,但是我没刷新,我可以切换菜单切换菜单的时候,每个请求都是无效的

但用户甚至不知道已经接口已经401,需要重新登录(因为单点登录,我在其他系统退出登录,那么目前系统的接口都会401),这就是需要解决的问题(不刷新不知道接口已经401)。

方案3-1-拦截一个必调的接口,做轮询

既然刷新的解决了,我要解决不刷新的时候的问题

场景再回忆一下,我登录目前的系统,另外的系统退出登录,目前的系统接口401,我需要知道已经401,并且去到登录页面

那就想到一个无感刷新的东西,去轮询接口,乍一看网络请求,用户信息的接口一直在做轮询

那就直接监听用户信息的接口,去做一个拦截,当用户在其他系统退出登录,后当前系统会通过轮询来调用接口,接口拦截响应,检测到401,就会退出登录

总结

文章主要是记录一下是实现的思路,遇到问题怎么解决,换个方向或许有更好的解决办法,一开是全局改代码的方法确实不是一个好的实现方法,能用简单的方式来实现功能,才是较为合理的

关于这个问题的解决方法其实也还有很多,想到了就可以记录下来,欢迎大家评论区讨论。

如果觉得有趣或有收获,请关注我的更新,给个喜欢和分享。您的支持是我写作的最大动力!

往期好文推荐

相关推荐
好奇的菜鸟26 分钟前
掌握 npm 核心操作:从安装到管理依赖的完整指南
前端·npm·node.js
diving deep29 分钟前
springboot集成日志配置文件
java·spring boot·后端·logback
源码云商1 小时前
基于 SpringBoot + Vue 的海滨体育馆管理系统设计与实现
vue.js·spring boot·后端
肥肠可耐的西西公主2 小时前
前端(小程序)学习笔记(CLASS 2):WXML模板语法与WXSS模板样式
前端·学习·小程序
逆袭的菜鸟X3 小时前
RxJS 高阶映射操作符详解:map、mergeMap 和 switchMap
前端
bubiyoushang8883 小时前
HTML5的新语义化标签
前端·html·html5
会飞的鱼先生3 小时前
vue3自定义指令来实现 v-copy 功能
前端·javascript·vue.js
陈天伟教授3 小时前
Web前端开发 - 制作简单的焦点图效果
java·开发语言·前端·前端开发·visual studio
_殊途3 小时前
前端三件套之html详解
前端·html
Themberfue4 小时前
RabbitMQ ⑥-集群 || Raft || 仲裁队列
linux·运维·分布式·后端·rabbitmq·ruby