ajax异步请求,拦截器的重定向页面无效问题(坑)

  • Post author:
  • Post category:其他

问题

拦截器拦截ajax请求,重定向的时候,前端页面无效,只会异步请求重定向页面,不会刷新当前页面。即 前端页面没反应,但是控制台可以看到,确实请求了。

分析

ajax异步请求,响应重定向的时候不会刷新当前页面,而是异步重定向。
因为ajax请求和当前页面不是同一次请求,所以异步的重定向,页面是不会刷新的。

解决办法

拦截器:

@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		
		....逻辑判断.....
			// 调用自定义重定向方法
			redirect(request,response);
			return false;
		}
		
	}
	
	// 对ajax的重定向进行处理
    public void redirect(HttpServletRequest request, HttpServletResponse response) throws IOException{
        //获取当前请求的路径:协议://服务器名:端口号/项目名
        String basePath = request.getScheme() + "://" + request.getServerName() + ":"  + request.getServerPort()+request.getContextPath();
        
        //如果request.getHeader("X-Requested-With") 返回的是"XMLHttpRequest"说明就是ajax请求,需要特殊处理 否则直接重定向就可以了
        if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
            //自定义响应头 告诉ajax我是重定向,用ajax进行判断。
            response.setHeader("REDIRECT", "REDIRECT");
            //自定义响应头 告诉ajax我重定向的路径
            response.setHeader("CONTEXTPATH", basePath+"/cdps/error/timeout");
           // response.setHeader("Content-Type", "application/json;charset=UTF-8"); 这句没必要
           // 设置这次请求状态码为403 禁止访问
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            
        }else{
        	// 如果不是ajax 就正常重定向
            response.sendRedirect(basePath + "/cdps/error/timeout");
        }
    }

js

对ajax添加complete方法:

	complete: function (xhr, status) {
			//拦截器实现超时跳转到登录页面
			// 通过xhr取得响应头
            var REDIRECT = xhr.getResponseHeader("REDIRECT");
            alert(REDIRECT);
            //如果响应头中包含 REDIRECT 则说明是拦截器返回的
            if (REDIRECT == "REDIRECT")
            {
                var win = window;
                while (win != win.top)
                {
                    win = win.top;
                }
                //重新跳转到拦截器中的路径
                win.location.href = xhr.getResponseHeader("CONTEXTPATH");
            }
        }

注意:拦截器中的响应头的key,要和js中获取的key一致。

坑:如果引用的外部js文件,一定记得清缓存

如果所有ajax都需要进行重定向的判断,可以加全局complete方法。用$.ajaxSetup({})

$.ajaxSetup( {
	complete: function (xhr, status) {
			//拦截器实现超时跳转到登录页面
			// 通过xhr取得响应头
            var REDIRECT = xhr.getResponseHeader("REDIRECT");
            alert(REDIRECT);
            //如果响应头中包含 REDIRECT 则说明是拦截器返回的
            if (REDIRECT == "REDIRECT")
            {
                var win = window;
                while (win != win.top)
                {
                    win = win.top;
                }
                //重新跳转到拦截器中的路径
                win.location.href = xhr.getResponseHeader("CONTEXTPATH");
            }
        }
});

全局ajax的Complete的问题:如果自己之前有complete函数,则不会生效。

解决办法1: 写成js的function,然后在complete里调用

function ajaxComp(xhr, status){
	 var REDIRECT = xhr.getResponseHeader("REDIRECT");
     alert(REDIRECT);
     //如果响应头中包含 REDIRECT 则说明是拦截器返回的
     if (REDIRECT == "REDIRECT")
     {
         var win = window;
         while (win != win.top)
         {
             win = win.top;
         }
         //重新跳转到拦截器中的路径
         win.location.href = xhr.getResponseHeader("CONTEXTPATH");
     }
}

ajax中:

		complete: function (xhr, status) {
	                layer.close(lay);
	                ajaxComp(xhr, status);
	            },

版权声明:本文为BigDevil_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。