问题
拦截器拦截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 版权协议,转载请附上原文出处链接和本声明。