一、问题简述:在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中测试验证。