web|在Cookie被禁用的情况下使用url rewrite机制保持Session

在做QQ空间上的应用时,遇到session丢失的问题,明明把登录用户的信息存在session里了,但是再访问时,就找不到了,session是一个新的session,也就是说,每次访问都被认为是一个新的session。
寻找原因:由于我们的程序是跑在QQ空间里,是QQ空间的应用页面提供一个iframe给我们展示我们的程序页面,iframe里和iframe外分别是不同的域名,问题出在这里,跨域情况下的cookie被称作“第三方cookies”,第三方cookies是不被支持的,所以,cookie不能被顺利地带到server端,因此,靠cookie来维持的session自然就丢失了。到目前为止,我实际测试:chrome和firefox没有做限制,IE 11下,将第三方域名添加到“受信任的站点”后可以带Cookie,Safari浏览器下禁用Cookie。
但是不能要求用户去添加“受信任的站点”啊,如果仅仅针对IE浏览器,可以用P3P解决方案:
详见http://blog.csdn.net/wauit/article/details/9875157
但是P3P对Safari浏览器不起作用。
于是,我们不得不自己找解决方案了。
JAVA EE的规范说:当cookie不能用时,使用url rewrite机制来保持session。这个大家都知道,只是长时间以来,我们习惯于在cookie环境下开发,不去理会这个特性了。那么url rewrite是怎么工作的呢?
在tomcat下,默认的设置就是:优先使用cookie,如果cookie被禁用,使用url rewrite,所以,不用修改任何配置。但是我们的代码要写东西:
先说一个不太好的解决方案:response.encodeURL(String); 看一下这个方法,注意,还有另外一个方法叫response.encodeUrl(String),是被弃用的API。
这个方法的功能是:把
http://xxx.com/abc?a=b
这样的url变成:
http://xxx.com/abc; jsessionid=D97956894C4330053A84DBE6FA7E8AC2?a=b
这样的url。
按理说我们应该把应用中每个链接上都套上这个方法,但是,一来太麻烦了,二来,没有判断cookie是否可用,如果cookie可用,cookie还是更好的方案,因为不必在url上带上session信息,以免拷贝分享一个URL时带上不必要的session信息。
其实,JSTL早就有解决方案,现在的JSTL也更方便使用了,我下载最新的1.2.1版本,比原来的1.1更加方便,直接加入jar包,在jsp头上引用就可以使用core标签了。
'>链接
生成的html:
链接
所以,以后不要再写href="https://www.it610.com/app/abc?a=b"这样的代码了,都用来代替吧,好处有:
1. 自动判断cookie是否可用,如果可用,返回原值,如果不可用,返回带jsessionid的URL
2. 自动补充ContextPath,例如我们正常应该写href="https://www.it610.com/abc?a=b",用c:url就不用写这个context path了,直接
3. 自动对URL进行base64编码,例如



生成的url是:/app/abc?a=%e4%b8%ad%e6%96%87'>链接
在实际使用中可以先定义好,再引用,也可以直接inline在href中:



链接
或者inline:
'>链接
4. 可以在后面再拼想要的参数:例如:
&v='>链接
小提示:
1. 我通常在inline使用时,href的值用单引号,这是为了区别里面value=""的双引号,实际上,两部分都使用双引号也是支持的。
2. 图片、css、javascript等不需要保持session的url就不要加了,一个是加大了不必要的运算量,另外,有些浏览器是异步加载的,可能你的登录存session的动作还没做完呢,图片的请求就到了,所以对这种请求做session没有意义。
3.







上面获得了sessionid根据下文可以得到session
结合http://blog.csdn.net/albertfly/article/details/51327419Java根据sessionId获取Session对象




【web|在Cookie被禁用的情况下使用url rewrite机制保持Session】

jsessionID 和session

1.我打开一个页面,1分钟不动,1分钟后jsessionid会改变吗?
如果你只是打开了登陆页面,而没有登陆,你根本就没有得到session,何谈session失效,得到session 的时机是你的登陆程序中用到了形如request.getSession()这样的语句,才会为你建一个session。
2.登陆后1分钟不动,然后jsessionid会变吗?
登陆后,你的确得到了session,也拥有了一个session id(jsessionid),如果你一分钟不动,属于你的session会失效。但此时你的jsessionid并没有变,因为此时你的jsessionid是放在了你浏览器的cookies中的。如果你这时进行操作,浏览器会将你的jsessionid传送到服务器,服务器拿这个jsessionid去找属于你的session,但不好意思,这时找不到了,因为超时后被干掉了。

    推荐阅读