问题的产生:  

  现如今Ajax在Web项目中应用广泛,几乎可以说无处不在。

  有时会碰到这样个问题:当Ajax请求遇到Session超时,应该怎么办?

  显而易见,传统的页面跳转在此已经不适用,因为Ajax请求是XMLHTTPRequest对象发起的而不是浏览器,在验证失败后的页面跳转无法反应到浏览器中,因为服务器返回(或输出)的信息被JavaScript(XMLHTTPRequest对象)接到了。

  那么应该怎么处理这种情况呢?

问题的解决之法:

  既然服务器返回的消息被XMLHTTPRequest对象接收,而XMLHTTPRequest对象又是在JavaScript的掌控之中,那么我们是否可以利用JavaScript来完成页面跳转呢?

  当然可以,而且很容易实现!但有一点,我们需要判断一下HTTP请求是否为Ajax请求(因为AJAX请求和普通的请求需要分开处理),这又如何判断呢?其实Ajax请求和普通的HTTP请求是不同的,这体现在HTTP请求的头信息中,如下所示:

上面两张图片是用火狐的Firebug截取的,前者为Ajax请求的请求头信息;后者是普通的HTTP请求头信息。注意第一图片被红框圈起来的部分,这就是Ajax请求与普通请求不同的地方,AJAX请求头中带有X-Requested-With信息,其值为XMLHttpRequest,这正是我们可以利用的地方。

Javascript代码

$.ajaxSetup方法是来设置AJAX请求默认选项的,我们可以认为是全局的选项设置,因此可以将这段代码提到外部JS文件中,在需要的页面引用。

/**
* 设置未来(全局)的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;
}

拦截器的部分代码:

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 登录过滤器
*  拥有Session是否失效和用户是否登录2个条件判断
*  如果是ajax请求则设置session超时
* @author Merlin.Ma
*
*/
public class LoginFilter implements Filter{
private String redirectUrl = "/login.html";
private String sessionKey = "userName";
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse rep = (HttpServletResponse) response;
HttpSession session = req.getSession();
if( session == null || session.getAttribute(sessionKey) == null){
//如果判断是 AJAX 请求,直接设置为session超时
if( req.getHeader("x-requested-with") != null && req.getHeader("x-requested-with").equals("XMLHttpRequest") ) {
rep.setHeader("sessionstatus", "timeout");
} else {
rep.sendRedirect( req.getContextPath() + redirectUrl);
}
}else {
chain.doFilter(request, response);
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String url = filterConfig.getInitParameter("redirectUrl");
String key = filterConfig.getInitParameter("sessionKey");
redirectUrl = url == null? redirectUrl:url;
sessionKey = key == null ? sessionKey : key ;
}
}

由上面代码可以看出,当Session验证失败(即Session超时)后,我们通过HttpServletRequest取得请求头信息X-Requested-With的值,如果不为空且等于XMLHttpRequest,那么就说明此次请求是Ajax请求,我们作出的反应就是向响应中添加一条头信息(自定义)并且使响应对象HttpServletResponse返回服务器错误信息(518状态是自己随便定义的);这些信息都会被JavaScript接收,那么下面的工作就要将由JavaScript代码了。

js--Ajax的小知识(二):处理ajax的session过期的请求的更多相关文章

  1. ajax的小知识---总是得到重复的数据

    按xmlhttp.open("GET","/try/ajax/demo_get.php",true);发送,可能会得到缓存中的结果; 可以改为xmlhttp.o ...

  2. CSS-DOM的小知识(二)

    上篇文章说到,通过element.style.property可以获得元素的样式,但是style属性只能够返回内嵌样式,对于外部样式表的样式和head中的style样式都无法获取,这就限制了此方法的使 ...

  3. JS,JQuery小知识

    http://blog.163.com/wumingli456@126/blog/static/28896414201112252456459/?suggestedreading&wumii

  4. JS的一些小知识

    1.     0.1+0.2==0.3? 结果为false 原因:由于计算机是用二进制来存储和处理数据数字,不能精确表示浮点数,而JavaScript是一种弱类型语言,没有相应的封装类来处理浮点数运算 ...

  5. 8 HTML&JS等前端知识系列之Ajax的例子

    what is ajax ? AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新 ...

  6. Ajax——异步基础知识(二)

    XML数据格式 首行必须是版本号和格式等信息 <?xml version="1.0" encoding="utf-8" ?> 最外层需要一个根节点进 ...

  7. 第24篇 js小知识和“坑”

    前面说了说了js的相关知识,基本上除了语法外,把项目常用的知识做了一个梳理,现在说下js的其它方面的知识,这些知识不成体系,属于不理解对于一般开发没什么太多影响,但如果理解清楚,可以更好去开发. js ...

  8. c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询

    天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. ​ ​不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...

  9. 11月10日上午ajax基础知识、用ajax做登录页面、用ajax验证用户名是否可用、ajax动态调用数据库

    1.ajax的基础知识 ajax是结合了jquery.php等几种技术延伸出来的综合运用的技术,不是新的内容.ajax也是写在<script>标签里面的. 如果使用ajax一定是要有1个处 ...

随机推荐

  1. Qt学习之路(2)------Qt中的字符串类

    QString QString的一些基本用法 basic.cpp #include <QTextStream> int main(void) { QTextStream out(stdou ...

  2. HDOJ/HDU 1075 What Are You Talking About(字符串查找翻译~Map)

    Problem Description Ignatius is so lucky that he met a Martian yesterday. But he didn't know the lan ...

  3. 排列的Java递归语言实现

    在做算法题的时候,发现排列经常被使用到,是一个重要的知识点, 下面是博主修改过的代码,初学者,如有不足,欢迎指出 import java.util.ArrayList; import java.uti ...

  4. JVM 字节码执行实例分析

    前言 最近在看<Java 虚拟机规范>和<深入理解JVM虚拟机>,对于字节码的执行有了进一步的了解.字节码就像是汇编语言,是 JVM 的指令集.下面我们先对 JVM 执行引擎做 ...

  5. 用slf4j统一管理日志总结

    用slf4j统一管理日志总结 参考网页:http://www.slf4j.org/ 一.使用slf4j统一管理并配置统一使用log4j日志 使用的jar:(slf4j-api-1.7.5.jar,jc ...

  6. JavaBean以及MVC模式

    JavaBean,  咖啡豆. JavaBean是一种开发规范,可以说是一种技术. JavaBean就是一个普通的java类.只有符合以下规定才能称之为javabean: 1)必须提供无参数的构造方法 ...

  7. iOS AvPlayer AvAudioPlayer音频的后台播放问题

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...

  8. 比較具体的handle机制

    Android的消息机制,用Android线程间通信的Message机制,Android中Handler的用法--在子线程中更新界面,handler机制 Android的消息机制(一) android ...

  9. MyEclipse10.0安装jad反编译插件

    1.下载反编译工具jad(下面提供下载) 将下载下来的jadstar158.zip解压缩,将jad.exe文件放入jdk安装目录下 如:C:\Program Files\Java\jdk1.6.0_2 ...

  10. Oracle 设置日志模式

    在NOARCHIVELOG模式下启动和运行一个数据库. 确定闪回恢复区的位置和归档日志目标目录的位置. 步骤一 为归档的重做日志配置FRA和单独的归档日志目标. 首先,设置FRA参数DB_RECOVE ...