拦截ajax请求跳转登录页面

拦截ajax请求跳转登录页面

场景

项目中使用springMVC的HandlerInterceptorAdapter拦截器拦截请求,如果session失效时,就自动跳转登录页面,但是如果是ajax请求时,就出现不能自动跳转登录页面的情况,也就是ajax请求的转发重定向都失效。

原因

参考:https://blog.csdn.net/mozha_666/article/details/86519642
简单概括为:

  1. ajax是局部刷新,不重写加载页面的,请求的最终结果都会返回到ajax封装的方法中。
  2. ajax默认是不支持重定向的

解决方法

因最终的跳转不能在后台去执行,所以需要配合后端何前台一起协作来完成,后台打标机,前台根据标机跳转。

后台代码

  1. 判断是否是ajax请求

    /**
     * 判断是否为ajax请求
     *
     * @param request
     * @param response
     * @return
     */
    private boolean isAjaxRequest(HttpServletRequest request, HttpServletResponse response) {
        try {
            //判断是否为ajax请求。
            if (request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
  1. 如果是ajax请求则打一个标记
   /**
     * ajax请求标记
     *
     * @param request
     * @param response
     * @param loginUrl
     */
    private void ajaxHttpToLogin(HttpServletRequest request, HttpServletResponse response, String loginUrl) {
        //如果是ajax请求响应头会有x-requested-with,自定义707状态码为ajax登录过期
        try {
            response.setHeader("SESSIONSTATUS", "TIMEOUT");
            response.setHeader("CONTEXTPATH", request.getContextPath() +loginUrl);
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);//403 禁止
        }catch (Exception e){
            e.printStackTrace();
        }
    }
  1. 拦截器调用,如图:
    在这里插入图片描述

前台

ajax属性介绍:http://www.w3school.com.cn/jquery/ajax_ajax.asp

前台的方法有两种,但是都是通过ajax的后置处理函数来完成的。

  1. 通过ajax的后置处理函数complete实现:
$.ajaxSetup({
    complete : function(XMLHttpRequest, textStatus) {    
		//拦截器实现超时跳转到登录页面
        // 通过xhr取得响应头
        var SESSIONSTATUS = xhr.getResponseHeader("SESSIONSTATUS");
        //如果响应头中包含 TIMEOUT 则说明是登录过期
        if (SESSIONSTATUS == "TIMEOUT"){
            var win = window;
            while (win != win.top){
                win = win.top;
            }
            //重新跳转到 login.html
            win.location.href = xhr.getResponseHeader("CONTEXTPATH");
        }        
  }
});

问题: 实现了complete后,可能某些组件里面实现了complete的会有影响。

  1. 重写ajax函数
/**
  * 重写ajax方法,使ajax登录失效时能正常跳转登录页
  */
 function rewriteAjax() {
     //首先备份下jquery的ajax方法
     var _ajax=$.ajax;

     //重写jquery的ajax方法
     $.ajax=function(opt){
         //备份opt中error和success、complete方法
         var fn = {
             error:function(XMLHttpRequest, textStatus, errorThrown){},
             success:function(data, textStatus){},
             complete:function(data, textStatus){}
         }
         if(opt.error){
             fn.error=opt.error;
         }
         if(opt.success){
             fn.success=opt.success;
         }
         if(opt.complete){
             fn.complete=opt.complete;
         }

         //扩展增强处理
         var _opt = $.extend(opt,{
             error:function(XMLHttpRequest, textStatus, errorThrown){
                 var SESSIONSTATUS = XMLHttpRequest.getResponseHeader("SESSIONSTATUS");
                 //如果响应头中包含 TIMEOUT 则说明是登录过期
                 if (SESSIONSTATUS != "TIMEOUT"){
                     //错误方法增强处理
                     fn.error(XMLHttpRequest, textStatus, errorThrown);
                 }
                 //登录的错误处理不用管,直接放行
             },
             success:function(data, textStatus){
                 //成功回调方法增强处理
                 fn.success(data, textStatus);
             },
             beforeSend:function(xhr){

             },
             complete: function (xhr,status) {
                 //拦截器实现超时跳转到登录页面
                 // 通过xhr取得响应头
                 var SESSIONSTATUS = xhr.getResponseHeader("SESSIONSTATUS");
                 //如果响应头中包含 TIMEOUT 则说明是登录过期
                 if (SESSIONSTATUS == "TIMEOUT"){
                     var win = window;
                     while (win != win.top){
                         win = win.top;
                     }
                     //重新跳转到 login.html
                     win.location.href = xhr.getResponseHeader("CONTEXTPATH");
                 }
                 //调用备份的后置处理
                 fn.complete(xhr, status);
             }
         });
         return _ajax(_opt);
     };
 }

目前我前台是采用这种形式处理的ajax登录拦截跳转的,对第三方插件的complete目前没有什么影响,不过重写的时候需要慎重

有问题欢迎评论区讨论

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值