情景描述:测试环境,设置session过期时间为1分钟。在session过期后,执行一个ajax请求,结果在Firebug中,出现如下错误提示:
这是ajax的跨域问题。首先想到的解决方案是使用jsonp,可能是我用的不对吧,没能解决问题。
不过,现在想一想,如果采用jsonp把这个问题解决了,难道我要把项目中所有的ajax都改为jsonp吗?如果是这样,那就疯了。
通过度娘,找到了靠谱的方法,这是原文地址 http://www.cnblogs.com/syjkfind/archive/2015/03/26/4370092.html
部分原文如下:
【参考的解决方法】
a.在session超时的情况下发ajax请求。返回200正常,并在json中指定状态码302和login.action地址
b.访问login.action。302重定向指向CAS服务器
c.访问CAS服务器登录授权。302重定向回login.action
d.访问login.action带有ticket。302重定向next_page(即一开始ajax请求的页)
e.访问next_page刷新整个页
【具体解决过程】
1.修改CAS授权过滤器,session无效的ajax请求先返回200正常,并在json中指定业务错误码session_lost
继承修改AuthenticationFilter的doFilter方法:
a.如果session中有assertion,通过,进入下一层(tomcat端向CAS服务器验证ticket)
b.(无assertion)如果有ticket,通过,进入下一层filter(tomcat端向CAS服务器验证ticket)
c.(无assertion无ticket)普通http请求,重定向到CAS服务器
d.(无assertion无ticket)ajax请求,返回200并在json中指定session_lost
e.改配置web.xml,指向新的AuthenticationFilter类,并且serverName要与NginX的域名匹配
2.在js的callback中处理session_lost,将网址定位到/login.action
window.location.href=/app/login.action
3.在java的/autoLogin中重新登录并根据参数next_page重定向,完成登录和刷新
(因为是普通http请求,会先跳转到CAS登录,回来建立session信息,然后再跳转到用户本来的页面)
如果完全按照【具体解决过程】,结果也需要修改所有的ajax请求。
找个懒惰的方法,最终的解决方法,在AuthenticationFilter中,添加如下代码:
//session超时后,ajax请求出现跨域问题的解决方法 if(ticket == null && assertion == null){ String requestType = request.getHeader("X-Requested-With"); //判断是否为ajax请求 if(null != requestType && requestType.equals("XMLHttpRequest")){ PrintWriter out = response.getWriter(); out.print("<script>window.top.location.href='"+urlToRedirectTo+"'</script>"); out.close(); return; } }