前两天做项目在处理session失效时使用springMVC拦截器拦截ajax请求,结果发现正常请求拦截没问题,ajax请求拦截到了,可是ajax success函数捕获数据是登录页的源码,查了一下资料 ,
https://my.oschina.net/zhk/blog/323452
明白了怎么回事 具体来说ajax是用XMLHttpRequest 对象用于和服务器交换数据。它的请求头区别于正常请求头,利用它的这个特点我们在它请求时将它与正常请求区别开来,既然在拦截器中重定向会被ajax中的success函数捕获登录页源码无法跳转登录页,那么我们可以采取在拦截器中设置响应头添加session失效标记的方法,并用jquery ajax中的complete事件得到响应头中的标记,在js中添加session失效时跳转页面的处理
关于complete事件【
complete(XHR, TS)
类型:Function
请求完成后回调函数 (请求成功或失败之后均调用)。
参数: XMLHttpRequest 对象和一个描述请求类型的字符串。
这是一个 Ajax 事件。
】
以下是我自己测试的代码
Spring-mvc.xml配置
<mvc:interceptors>
<mvc:interceptor>
<!--需要过滤的路径映射 -->
<mvc:mapping path="/**" />
<!—不过滤的路径映射-->
<mvc:exclude-mapping path="/css/**"/>
<mvc:exclude-mapping path="/fonts/**"/>
<mvc:exclude-mapping path="/images/**"/>
<mvc:exclude-mapping path="/js/**"/>
<mvc:exclude-mapping path="/ueditor/**"/>
<mvc:exclude-mapping path="/upload/**"/>
<!—自定义的拦截器注册-->
<bean class="com.rescam.interceptor.AuthInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
自定义拦截器代码
package com.rescam.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
//继承HandlerInterceptorAdapter类
public class AuthInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
String ctxPath = request.getContextPath();//获取项目名
String uri = request.getRequestURI();//获取请求资源名
String qs = request.getQueryString();//获取请求参数
String ctrlName = uri.replace(ctxPath + "/", "");//去掉请求资源名中的项目名
Object user = session.getAttribute("manager");
/*
此处逻辑是先判断session是否失效
然后排除登录页
接着根据请求头判断是正常请求还是ajax请求
*/
if (user == null) {
//注:此处排除登录页的逻辑处理针对我测试的项目,不是固定的(根据项目实际情况灵活处理)
if((qs==null&& !ctrlName.equalsIgnoreCase("manger/login")) ||
(qs != null &&!qs.equalsIgnoreCase("url=login"))) {
if (request.getHeader("x-requested-with") != null &&
request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
response.setHeader("sessionstatus", "timeout");//设置session失效时的响应头标记
} else {
response.sendRedirect(ctxPath + "/page/show?url=login");
}
return false;
}
}
return true;
}
}
jquery ajax请求中需要加上
$.ajax({
url : basePath+'/colorScheme/deletes',
type : 'post',
data : {
'colorSchemeIds' : dels
},
dataType : 'json',
success : function(data) {
//此处在session失效时ajax请求被拦截器拦截到后 返回的是一个响应头
//同时success回调函数依然会执行 只不过此时data是 null 因此我在此加上if
//防止session失效时执行下面程序时报错
if(data && data != null){
if (data.success) {
dt.ajax.reload(null, false);
}
}
},
complete : function (XMLHttpRequest, textStatus) {
//使用XMLHttpRequest对象获取session失效响应头标记
var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus"); if(sessionstatus=="timeout"){
//跳转登录页
window.location.replace(basePath + "/page/show?url=login");
}
},
error : function(){
alertMsg("请求失败!");
}
});
});
经过测试 ,在session失效时 jquery ajax请求成功跳转登录页
注:对于 .post()、 . p o s t ( ) 、 .get()需要特别处理一下
以下摘自
http://www.css88.com/jqapi-1.9/jQuery.post/
从 jQuery 1.5开始,success回调函数还传递一个“jqXHR”对象 ( 在 jQuery 1.4中 ,它传递的是XMLHttpRequest对象)。用 POST 获取的页面是从来不会被缓存, 所以这些请求中的 cache 和 ifModified 选项在 jQuery.ajaxSetup() 是无效的。
The jqXHR Object(jqXHR 对象)
从jQuery 1.5开始,所有jQuery的Ajax方法都返回一个XMLHTTPRequest对象的超集。这个通过 .post()方法