关于在EOVA中session失效时跳转登录页
核桃小王子 发布于116月前 2答/3115阅

一、问题简述:在EOVA中当session失效时我们需要跳转到登录页面让用户重新登陆,但登录页面会内嵌到框架中交互效果十分不爽,发现大家也遇到相同问题,因此修改一下。

二、解决原理:我采用的是前端解决方案,追根溯源,我们都知道前端与服务端交互的两种方式,一种是url跳转另一种是ajax调用。这两种方式EOVA已经为我们处理了session失效的判断和处理,只是处理方式上有些小BUG。

三、url跳转的解决方案:这个比较简单,就是前端框架嵌套层数太多,只要回归首层,再调用/toLogin就OK了,我修改了{webroot}/eova下的login.html和init.html两个文件中的禁止登录页内嵌的代码,并将代码提到脚本的最前面执行,修改内容如下

(ps:知道你们想直接复制代码,来吧!)

// 禁止登录页内嵌
//if (window != top) {
//  parent.location.href = location.href;
//}
function getRootWin() {
  var win = window;
  while (win != win.parent) {
    win = win.parent;
  }
  return win;
}
var rootWin = getRootWin();
if (rootWin != window) {
  rootWin.onbeforeunload = null;
  rootWin.location.replace('/toLogin');
}

修改完这两个文件后,当session失效时再点击主界面的任意菜单即可实现跳转登录。

四、ajax调用的解决方案:

1、修改{webroot}/ui/easy/easy.js下的两处内容如下:

/**
 * 
 * 通用错误提示
 * 
 * 用于datagrid/treegrid/tree/combogrid/combobox/form加载数据出错时的操作
 * 
 * @author 孙宇
 * 
 * @requires jQuery,EasyUI
 */
sy.onLoadError = {
	onLoadError : function(XMLHttpRequest) {
		var sessionStatus = XMLHttpRequest.getResponseHeader("sessionStatus");
		if (sessionStatus == "timeout") {
			//跳转的登录页面
			var rootWin = getRootWin();
			rootWin.onbeforeunload = null;
			rootWin.location.replace('/toLogin');
		} else if (parent.$ && parent.$.messager) {
			parent.$.messager.progress('close');
			parent.$.messager.alert('错误', XMLHttpRequest.responseText);
		} else {
			$.messager.progress('close');
			$.messager.alert('错误', XMLHttpRequest.responseText);
		}
	}
};
/**
 * 改变jQuery的AJAX默认属性和方法
 * 
 * @author 孙宇
 * 
 * @requires jQuery
 * 
 */
$.ajaxSetup({
	cache: false,
	contentType: 'application/x-www-form-urlencoded;charset=utf-8',
	error : function(XMLHttpRequest, textStatus, errorThrown) {
		//通过XMLHttpRequest取得响应头,sessionStatus
		var sessionStatus = XMLHttpRequest.getResponseHeader("sessionStatus");
		if (sessionStatus == "timeout") {
			//跳转的登录页面
			var rootWin = getRootWin();
			rootWin.onbeforeunload = null;
			rootWin.location.replace('/toLogin');
		} else {
			try {
				parent.$.messager.progress('close');
				parent.$.messager.alert('错误', XMLHttpRequest.responseText);
			} catch (e) {
				alert(XMLHttpRequest.responseText);
			}
		}
	}
});

//新增获取根节点的函数
function getRootWin() {
	var win = window;
	while (win != win.parent) {
		win = win.parent;
	}
	return win;
}


2、修改{webroot}/eova下include.html文件,将easy.min.js引用暂时改为easy.js便于调试

<script type="text/javascript" src="${STATIC!}/ui/easy/easy.js"></script>

这样在调用ajax时就可以实现跳转到登录页面了。

不过这个现在有点问题,在session失效后,第一次调用ajax访问还会出现错误对话框,例如我用到了主从表窗口,点击主表内容ajax刷新明细表第一次会出现如下图所示界面:


之后再有调用就会回到登录界面!

针对以上问题,我在工程中新建了一个处理器 AjaxHandler.java,主要处理session失效时ajax请求返回timeout信息,源码如下:

import com.jfinal.handler.Handler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 处理Ajax调用Session异常情况
 * Created by sdjnz on 2016/7/12.
 */
public class AjaxHandler extends Handler {
  @Override
  public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
    if (request.getSession().getAttribute("user") == null) {
      if (request.getHeader("x-requested-with") != null //如果是ajax请求响应头会有,x-requested-with;
          && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
        response.setHeader("sessionstatus", "timeout");
      }
    }
    super.next.handle(target, request, response, isHandled);
  }
}

在继承自EovaConfig的自定义AdminConfig.java文件中Override了configHandler方法。

public class AdminConfig extends EovaConfig {
  @Override
  public void configHandler(Handlers me) {
    AjaxHandler ajaxHandler = new AjaxHandler();
    me.add(ajaxHandler);
    super.configHandler(me);
  }

//其他复写方法略。。。。。。。
}

这样就不会出现第一次失效的对话框了

以上内容均在Chrome 版本 51.0.2704.106 m中测试验证。



[沙发] 林羽
Nice....... +30G(先记着)
最佳
[地板] 烬TMC
赞个赞个赞个赞个赞个赞个赞个赞个赞个赞个
提交评论