完美解决ajax访问遇到Session失效的问题

 更新时间:2016年06月03日 11:23:43   投稿:jingxian  
下面小编就为大家带来一篇完美解决ajax访问遇到Session失效的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

最近由于一个项目,模块切换为ajax请求数据,当Session失效后,ajax请求后没有返回值,只有响应的html:<html><script type='text/javascript'>window.open('http://192.168.0.118:8080/welcomeAction/loginUI.do','_top');</script></html>

现在Ajax在Web项目中应用广泛,几乎可以说无处不在,这就带来另外一个问题:当Ajax请求遇到Session超时,应该怎么办?

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

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

方法

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

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

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

下面看一下代码如何实现。

Interceptor过滤器

在使用Struts2时,我们一般使用Interceptor(拦截器)来拦截权限问题。

拦截器部分代码:

public String intercept(ActionInvocation invocation) throws Exception {
    // TODO Auto-generated method stub
    ActionContext ac = invocation.getInvocationContext();
    HttpServletRequest request = (HttpServletRequest) ac.get(StrutsStatics.HTTP_REQUEST);
    String requestType = request.getHeader("X-Requested-With");
    System.out.println("+++++++++++++++++++++++reqestType:"+requestType);
    HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE);
//    String basePath = request.getContextPath();
    String path = request.getContextPath(); 
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; 
    //获取session
    Map session = ac.getSession();
    //判断session是否存在及session中的user信息是否存在,如果存在不用拦截
    if(session != null && session.get(Constants.FE_SESSION_BG_USER) != null && session.get(Constants.FE_SESSION_BG_AUTH) != null){
      System.out.println(invocation.getProxy().getActionName()+"++++++++++++++++++++++++");
      System.out.println("namespace:"+invocation.getProxy().getNamespace());
      //访问路径
      String visitURL = invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + Constants.FE_STRUTS_ACTION_EXTENSION;
      visitURL = visitURL.substring(1);
      Map<String , Object> authMap = (Map<String, Object>) session.get(Constants.FE_SESSION_BG_AUTH);
      Map<Integer, String> actionMap = (Map<Integer, String>) authMap.get(Constants.FE_BG_ACTIONMAP);
      if(actionMap != null && !actionMap.isEmpty() && visitURL != null){
        if (actionMap.containsValue(visitURL)) {
          System.out.println(visitURL+"-----------------------");
          return invocation.invoke();
        } else{
          String forbidden = basePath + Constants.FE_BG_FORBIDDEN;
          response.sendRedirect(forbidden);
          return null;
        }
      }
      return invocation.invoke();
    }else{
      if(StringUtils.isNotBlank(requestType) && requestType.equalsIgnoreCase("XMLHttpRequest")){
        response.setHeader("sessionstatus", "timeout"); 
        response.sendError(518, "session timeout."); 
        return null;
      }else {
        
        String actionName = invocation.getProxy().getActionName();
        System.out.println(actionName);
        //如果拦截的actionName是loginUI或login,则不做处理,否则重定向到登录页面
        if (StringUtils.isNotBlank(actionName) && actionName.equals(Constants.FE_BG_LOGINUI)) {
          return invocation.invoke();
        }else if(StringUtils.isNotBlank(actionName) && actionName.equals(Constants.FE_BG_LOGIN)){
          return invocation.invoke();
        }else{
          String login = basePath + "/" + Constants.FE_BG_LOGIN_NAMESPACE + "/" + Constants.FE_BG_LOGINUI + Constants.FE_STRUTS_ACTION_EXTENSION;
//        System.out.println("+++++++++++++++++++++++++++basePath:"+basePath);
//        response.sendRedirect(login);
          PrintWriter out = response.getWriter();
//        out.println("<html>"); 
//        out.println("<script>"); 
//        out.println("window.open ('"+login+"','_top');"); 
//        out.println("</script>"); 
//        out.println("</html>");
          out.write("<html><script type='text/javascript'>window.open('"+login+"','_top');</script></html>");
          return null;
        }
      }
    }
    
  }

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

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;
}

以上这篇完美解决ajax访问遇到Session失效的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Ajax与JSON的一些学习总结

    Ajax与JSON的一些学习总结

    Ajax技术的核心是XMLHttpRequest对象(简称XHR),可以通过使用XHR对象获取到服务器的数据,然后再通过DOM将数据插入到页面中呈现。虽然名字中包含XML,但Ajax通讯与数据格式无关,所以我们的数据格式可以是XML或JSON等格式
    2012-08-08
  • Ajax技术(WEB无刷新提交数据)-

    Ajax技术(WEB无刷新提交数据)-

    Ajax技术(WEB无刷新提交数据)-...
    2006-07-07
  • AJAX中文乱码PHP中完美解决方法

    AJAX中文乱码PHP中完美解决方法

    AJAX中文乱码问题,经过一个下午的努力终于完美解决,现将心得写下来,希望对那些还困绕在这个问题而头痛不已的人们有所帮助
    2012-09-09
  • HTTP状态代码及其定义解析 Ajax捕捉回调错误参考

    HTTP状态代码及其定义解析 Ajax捕捉回调错误参考

    当用户试图通过 HTTP 访问一台正在运行 Internet 信息服务 (IIS) 的服务器上的内容时,IIS 返回一个表示该请求的状态的数字代码。状态代码可以指明具体请求是否已成功,还可以揭示请求失败的确切原因
    2013-11-11
  • layui Ajax请求给下拉框赋值的实例

    layui Ajax请求给下拉框赋值的实例

    今天小编就为大家分享一篇layui Ajax请求给下拉框赋值的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • 浅谈Ajax跨域Session和跨域访问

    浅谈Ajax跨域Session和跨域访问

    这篇文章主要介绍了Ajax跨域Session和跨域访问的相关问题,以及需要注意的地方,这里推荐给大家
    2014-12-12
  • 完成了AJAX树附原理分析

    完成了AJAX树附原理分析

    周五完成了计划中的RAILS框架中实现的AJAX树目录,今天才有空记录一下。
    2009-02-02
  • 使用Ajax技术通过XMLHttpRequest对象完成首页登录功能

    使用Ajax技术通过XMLHttpRequest对象完成首页登录功能

    这篇文章主要介绍了使用Ajax技术通过XMLHttpRequest对象完成首页登录功能,很不错的尝试,需要的朋友可以参考下
    2014-08-08
  • ajax 技术和原理分析

    ajax 技术和原理分析

    大家都知道ajax并非一种新的技术,而是几种原有技术的结合体。它由下列技术组合而成。
    2010-04-04
  • AJAX 异步传输数据的问题

    AJAX 异步传输数据的问题

    暂时把script中的‘+’都用‘-’代替,index += 1;改成index -= -1;呵呵,以后有人看到这段自动生成的诡异脚本,不知道会作何感想,但现在也只能如此。
    2008-12-12

最新评论