当Ajax请求遇到Session超时
2014-03-16 13:59
197 查看
前言
B/S应用中,用户登录应该是必不可少的一项;一般情况下我们会将登录用户的信息存储在Session中,当用户请求服务器资源时,在请求到达资源之前需要验证Session中是否有登录用户的信息,若是没有(用户没有登录或者Session超时),我们会让浏览器跳转到登录页面;如果Session存在且未超时,才可访问资源。现在Ajax在Web项目中应用广泛,几乎可以说无处不在,这就带来另外一个问题:当Ajax请求遇到Session超时,应该怎么办?
显而易见,传统的页面跳转在此已经不适用,因为Ajax请求是XMLHTTPRequest对象发起的而不是浏览器,在验证失败后的页面跳转无法反应到浏览器中,因为服务器返回(或输出)的信息被JavaScript(XMLHTTPRequest对象)接到了。
那么应该怎么处理这种情况呢?
方法
既然服务器返回的消息被XMLHTTPRequest对象接收,而XMLHTTPRequest对象又是在JavaScript的掌控之中,那么我们是否可以利用JavaScript来完成页面跳转呢?当然可以,而且很容易实现!但有一点,我们需要判断一下HTTP请求是否为Ajax请求(因为AJAX请求和普通的请求需要分开处理),这又如何判断呢?其实Ajax请求和普通的HTTP请求是不同的,这体现在HTTP请求的头信息中,如下所示:
![](http://img.my.csdn.net/uploads/201303/20/1363753928_3973.png)
![](http://img.my.csdn.net/uploads/201303/20/1363753955_2586.png)
上面两张图片是用火狐的Firebug截取的,前者是普通的HTTP请求头信息;后者为Ajax请求的请求头信息。注意第二图片被红框圈起来的部分,这就是Ajax请求与普通请求不同的地方,AJAX请求头中带有X-Requested-With信息,其值为XMLHttpRequest,这正是我们可以利用的地方。
下面看一下代码如何实现。
如何判断一个请求是否为AJAX请求
普通请求与ajax请求的报文头不一样,通过如下Java代码
![](http://zwllxs.iteye.com/images/icon_star.png)
String requestType = request.getHeader("X-Requested-With");
如果requestType能拿到值,并且值为XMLHttpRequest,表示客户端的请求为异步请求,那自然是ajax请求了,反之如果为null,则是普通的请求
Servlet过滤器
在Java Servlet规范中,我们一般使用Filter来处理这种权限问题,在请求到达目标资源之前进行拦截。部分Filter代码:
[java]
view plaincopy
HttpSession session = httpRequest.getSession();
if (null != session.getAttribute("curUser")) {
chain.doFilter(request, response);
return;
}
/**
* 当HTTP请求来自AJAX并且用户的Session已经超时时, 这时页面会没有任何反应, 因为向AJAX请求
* 重定向或者输出一段JS实现跳转都是无法完成的. 因此这里实现当上述情况发生时, 向AJAX请求返
* 回特定的标识(添加到响应对象中), 可以在定义AJAX请求完成回调方法时得到这个标识, 进而提示
* 用户并完成JS跳转.
*/
String requestType = httpRequest.getHeader("X-Requested-With");
if (!StringUtils.isEmpty(requestType) && requestType.equalsIgnoreCase("XMLHttpRequest")) {
httpResponse.setHeader("sessionstatus", "timeout");
httpResponse.sendError(518, "session timeout.");
return;
}
// httpResponse.sendRedirect(httpRequest.getContextPath() + "/index.html");
/**
* 由于Web端使用iframe嵌套, 因此直接重定向到登录页面并不能总是完成地很完美, 比如HTTP请求来自
* iframe对象的时候, 只能让iframe加载到index.html, 体验不够好; 所以在这里将直接重定向改为向
* 页面输出一段JS代码来实现使顶部window跳转到默认的登录页面.
*/
String jsCode = "<script type='text/javascript'>" +
"var p=window;while(p!=p.parent){p=p.parent; } p.location.href='" +
httpRequest.getContextPath() +
"/index.html'</script>";
PrintWriter writer = httpResponse.getWriter();
writer.print(jsCode);
writer.flush();
writer.close();
由上面代码可以看出,当Session验证失败(即Session超时)后,我们通过HttpServletRequest取得请求头信息X-Requested-With的值,如果不为空且等于XMLHttpRequest,那么就说明此次请求是Ajax请求,我们作出的反应就是向响应中添加一条头信息(自定义)并且使响应对象HttpServletResponse返回服务器错误信息(518状态是自己随便定义的);这些信息都会被JavaScript接收,那么下面的工作就要将由JavaScript代码了。
Javascript代码
$.ajaxSetup方法是来设置AJAX请求默认选项的,我们可以认为是全局的选项设置,因此可以将这段代码提到外部JS文件中,在需要的页面引用。[javascript]
view plaincopy
/**
* 设置未来(全局)的AJAX请求默认选项
* 主要设置了AJAX请求遇到Session过期的情况
*/
$.ajaxSetup({
type: 'POST',
complete: function(xhr,status) {
var sessionStatus = xhr.getResponseHeader('sessionstatus');
if(sessionStatus == 'timeout') {
var top = getTopWinow();
var yes = confirm('由于您长时间没有操作, session已过期, 请重新登录.');
if (yes) {
top.location.href = '/skynk/index.html';
}
}
}
});
/**
* 在页面中任何嵌套层次的窗口中获取顶层窗口
* @return 当前页面的顶层窗口对象
*/
function getTopWinow(){
var p = window;
while(p != p.parent){
p = p.parent;
}
return p;
}
这里的JavaScript代码使用了JQuery,其实道理是一样的,不用JQuery也一样处理:在请求完成的回调函数中通过XMLHTTPRequest对象得到响应头sessionstatus的值(也就是我们在Filter中设置的),如果值不为空且等于我们在Filter中设置的字符串,那么提示用户Session已经过期,询问是否需要跳转到登录页面;当用户点击的了“确定“按钮,那么我们就将浏览器重定向到登录页面。
至此,也就完成了上面提出的问题。
需要注意的是,ajaxSetup中的complete的function需要在一般ajax请求的success方法处理return后才处理
更多
相关文章推荐
- mvc下ajax请求遇到session超时简单处理方式
- 当 jquery 发送 ajax 请求的时候遇到服务端session过期超时返回 302 跳转登陆页面的时候怎么办的处理方法
- mvc下ajax请求遇到session超时简单处理方式
- 当Ajax请求遇到Session超时
- DWZ(JUI) 教程 Ajax请求session超时处理流程
- Ajax请求Session超时的解决办法:拦截器 + 封装jquery的post方法
- Session超时后,Ajax请求处理方式
- Ajax请求Session超时的解决办法:拦截器 + 封装jquery的post方法
- Ajax请求Session超时的解决办法:拦截器 + 封装jquery的post方法
- Ajax请求Session超时的解决办法:拦截器 + 封装jquery的post方法
- Session超时后,Ajax请求处理方式
- Ext下,ajax请求和普通http请求,session超时转到登录页面的解决方案
- spring security:ajax请求的session超时处理
- java Servlet Filter 拦截Ajax请求,统一处理session超时的问题
- Ajax请求Session超时的处理
- Spring Mvc Session超时easyui tab页中ajax请求跳出问题
- session 超时,处理ajax请求
- Ajax&Json - 异步请求遇到session失效
- Ajax请求处理Session超时
- DWZ(JUI) 教程 Ajax请求session超时处理流程