用户
 找回密码
 入住 CI 中国社区
搜索
查看: 17169|回复: 9
收起左侧

[讨论/交流] IE8的session问题解决,供大家参考

    [复制链接]
发表于 2009-12-8 21:44:10 | 显示全部楼层 |阅读模式
今天遇到一个客户用IE8访问CI的session丢失问题,我用的是CI 1.7.1 ,使用的是CI自带的SESSION类。

问题比较奇怪,因为在自己这里IE8是支持的。
通过查找论坛帖子,换用了KNDB session,不过问题依旧。不过大概看出点问题,好像是有个director,IE8会把COOKIE的有效期给清了。

然后搜国外的论坛,发现CI的SESSION对IE8支持有问题,还有人报BUG。从论坛上分析,CI的IE8主要是2个问题:

1、重定向会导致IE8的sess_match_useragent不正确,比如论坛上有人集成了PAYPAL,然后回来的时候IE8的USERAGNET就变成了IE7,导致COOKIE过期
2、重定向会导致COOKIE的有效期过期。然后有2,3中做法。我参考了其中的一种,尝试修改,解决了问题。我猜测可能是我用AJAX有个重定向导致了COOKIE过期,做法如下:

The problem lies in the fact that IE8 removes the CI session cookie even though the expiration timestamp should prevent this
NOTE: Above happens especially when you would like to use clientredirect via: header( “Location: ” ) call instead of following the linkclick
My solution is to patch one line of the Session::_set_cookie() method in your Session.php:function _set_cookie($cookie_data = NULL)
   
{
        
/* HERE WE HAVE SOME CODE WHICH WE DO NOT TOUCH...   */
        /* ... WE CHANGE THE setcookie() CALL BY CHANGING THE */
        /* THIRD PARAM TO 0 (originally the third parameter  */
        /* was set to $this->sess_expiration + time()        */

        // Set the cookie
        
setcookie(
                    
$this->sess_cookie_name,
                    
$cookie_data,
                    
0,   // <--- HERE YOU PLACE THE 0
                    
$this->cookie_path,
                    
$this->cookie_domain,
                    
0
               
);
   
}


By patching as described above (third param of setcookie set to 0)we instruct the browser not to delete the cookie until the browsersession is finished (so in most cases until the browser is closed).
What we might also want to do is to make sure we have following call somwhere in code of our controller:$this->session->set_userdata('last_activity' => $this->session->_get_time());

This ensures that the lastActivity (in CI 1.7.2) is updated indatabase to the current timestamp. Thanks to this CI session will bedestroyed after the inactivity time passes (so the “inactivity logout”will still work even though the cookie will not be deleted by thebrowser..) <- beware however that CI must still execute call to_sess_gc() to destroy the session.. and this call depends on value of$gc_probability.. so when testing this the best is to set the$gc_probability to 100)
NOTE: If you implement this you might want to omit call to$this->session->_get_time() since this is marked as CI privatemethod. In this case write your own method to get the time


基本上我就跟着这个操作,在system/libraries/Session.php的类里面的function _set_cookie($cookie_data = NULL)这个方法的($this->now - 31500000)改成0,然后再session建立的
set_userdata这里面多加一个变量
$this->session->set_userdata('last_activity' => $this->session->_get_time());这样子就会保持到关闭IE才过期。
通过这个方法解决了问题。

顺便说一下,下午调试过程中从贴子里面学到的一招:
IE8的COOKIE调试可以先按F12,再点cache里面的view cookie information 就能看到COOKIE的数据
FIREFOX反正用developer插件就能搞定,就不多说了
建议把COOKIE数据在服务器存储在数据库里面,可以从数据库里面查看SESSION数据是IP变化了还是useragent发生变化导致的问题。

今天为了SESSION丢失的问题,花了一天的时间,希望对大家有点帮助。

评分

参与人数 1威望 +5 收起 理由
Hex + 5 精品文章

查看全部评分

发表于 2010-1-21 15:23:35 | 显示全部楼层
感动啊。。。。我也遇到了这个问题,幸好我的第一反应是来论坛看看,所以只是按楼主说的改了改就好用了,没费多大力气,非常感谢!!!

虽然好像论坛上大家都不用CI自带的session类,但是像我这样还用CI购物车类的小白(也需要利用session)来说就很有用了呵呵。希望CI下个版本考虑session和ie8的兼容问题,至少可以直接把CI购物车类修改成好用的。
发表于 2010-1-26 19:51:24 | 显示全部楼层
我不明白为什么你们要这样处理.
SESSION本来就是基于服务器上的,每一次关闭浏览器之后所产生的SESSION都是不相同的.
COOKIS是基于客户端的,所以才可以保存下载.
CI的SESSION机制问题本来就是很有问题,把SESSION的概念COOKS化了.
为什么不走正统路线,反而延续了CI这个错误概念呢?
发表于 2010-1-27 10:56:52 | 显示全部楼层
楼上的说法就不完全正确了,CI 使用 Cookie 作为 Session,是有作者自己的考虑的,不能说不用 PHP Session 就是错误的,比如用数据库存储 Session 也是错误的吗?呵呵
发表于 2010-7-23 08:39:17 | 显示全部楼层
将就着过吧。还能怎样啊。
发表于 2010-7-25 19:42:54 | 显示全部楼层
我说呢,IE8直接登陆不了。其他浏览器下也不能按照config里设置的超时时间,有时候10几分钟,有时候1分钟就退出了。
发表于 2010-7-30 15:24:52 | 显示全部楼层
好东西,收藏先 :)
发表于 2011-2-18 18:36:59 | 显示全部楼层
操作步骤 没有呀 CI的老问题了 哎
发表于 2011-2-18 20:04:24 | 显示全部楼层
回复 8# le_el


    不要纠结在这个问题上,有问题就换我发布的  Session 类库。
发表于 2011-2-21 10:04:36 | 显示全部楼层
回复 9# Hex


    我用了还是没解决 郁闷啊 /application/Session.php 这样 然后禁用Session数据库支持 是这样吧? 还是不行

本版积分规则