日期:2014-05-16  浏览次数:20368 次

[Extjs]页面超时后重新登录访问该页面依然超时

[该日志写于2011/6/3 17:31]

?

?

困扰多时的超时问题终于解决了:

?????? 从今天中午开始下定决心解决此问题。首先是要重现,一个也算比较偶然的情况,我在IE中登录后,等待超时,(我设置为2分钟,不用等很长时间)。然后点“基本信息管理”中的“大区信息管理”,也不知道是那根神经动了,就想到点这个,冥冥之中啊。这时超时,返回登录页面,重新登录后,再点“大区信息管理”,再次会话超时,成功重现。

?????? 既然重现了,我就开始使用火狐调试了,在成功出现超时后,发现firebug端有红叉叉,结果是“/common/getCurrentFormPermission”返回的数据有问题,这个actionsession失效后,直接返回空字符串,Ext.decode无法解析空字符串报错,我在我本机的代码上改造了相关代码,让超时时也弹一个超时界面,结果发现弹出了两个超时界面,这时就有点意思了,我将两个提示信息用不同的问题区别,发现viewport.js中的监听超时函数和每个页面的异步调用的getCurrentFormPermission都执行了。所以可以肯定超时后,点击菜单url的,也弹出超时窗口。

?????? 这时,我将logger.info("超时:targetURL=" + targetURL + ",request.getContextPath()=" + request.getContextPath());debug调到info,之前一直是info级别,导致打印超时url的信息没有打印,没有第一时间想到,点击左边菜单的url也会触发超时监听函数。不过不算太糟。改好后重新测试,果然印证的访问菜单url会超时。

?????? 到了这一步,我将filter中做了url的“/static/”过滤,不打印访问的静态url。同时也验证了静态url不走SpringMVC。日志界面变得清爽很多。于是通过ie和火狐的对比,发现火狐不会出现重新登录后超时的问题,超时后重新登录点击菜单,还是会在日志发现发出了url请求,而真正令人兴奋的是,在ie的测试中发现,超时后重新登录后点击菜单,在日志中没有发现左边菜单的url请求,而且有菜单url对应的js代码加载后的按钮初始化调用的Ext.Ajax。至此,可以定位为是浏览器缓存的问题。原来只知道点击左边菜单右边加一个panel的实际上是viewport中的autoLoad起作用的,但现在明确了这个autoLoad实际上是一个Ext.Ajax!!!只可能是这样,才能被filter截获并给responseheader赋值一个sessiontimeout的属性。

?????? 我马上想到之前我在iteye上看到偶然看到的一篇介绍浏览器缓存的文章,可惜没有收藏,于是在网上搜刮了一番,终于找到了《HTTP协议缓存策略深入详解之etag妙用》,在此不解释怎么又找到了,总之花了一番精力,而且我现在也想不起来了。当然,遗憾的是,这篇文章并没有直接告诉我解决方案,于是google之,换了几次关键字,最终“java url 不缓存”成功了。第一条结果就是标准答案。最终我在Filter中加了三句话,黄金的三句话啊。问题得到完满解决。

?????? 我们的超时机制是这样的:拦截所有的url,在进入action之前先做一个判断,如果session为空或者sessionuser不为空,在判断是不是Ajax请求,只有是Ajax请求,js端的超时监听器才会起作用。如果是,在responseheader里设置一个sessiontimeout属性。结束后,注意,这里说的结束,其实对于点击左边菜单情形来说,右边的js代码已经加载了!只有这样我之前说的弹出两个超时窗口才有可能。Viewport.js中的超时监听器捕捉到后弹出超时窗口。

?????? 对于ie来说,第一次超时返回到登录界面时已经将访问左边菜单的url信息缓存了,返回的结果的response中就带有sessiontimeout的属性!,所有再次点击的时候浏览器不想server端发出请求,直接从缓存中得到了返回结果。成功的使超时监听器触发了。Filter强制设置了no-cache