Codeigniter会话用ajax调用

lam*_*ler 23 cookies ajax session jquery codeigniter

我的CodeIgniter应用程序使用会话库并将数据保存到数据库.

我遇到了一些问题,在某个ajax调用之后会创建空白会话.

经过调查,似乎有2个同时发生的函数调用需要进行会话验证.一个人会失败而另一个会没事的.

我能够通过不让它们同时发射来解决这个问题.但我仍然不明白原因为什么它会失败.是否与一次更新用户cookie和第二次呼叫失效有关?或者也许在阅读数据库时它会以某种方式死掉?

我稍微查看了Session核心类,但没有发现任何线索.

如果有任何人遇到同样的问题,我会感激任何关于如何调试或原因是什么的建议.

谢谢!

编辑:

我原本说有408状态回归.这是一个无关的案例.

这是并行触发MyVar.refresh()的函数:

function (event)
{
    var self$ = this.a$;
    var uid  = this.b$.val();
    var tid  = this.c$.val();
    var jqxhr = $.post('/controller1/index',{'uid':uid,'tid':tid,'action':true},function(re)
    {
        if(re.message != 'success')
        {
            MyVar.alert('<span class="msg_error sprite"></span>' + re.error);
            MyVar.refresh();
        } 

    },'json');
    MyVar.refresh();
    return stopDefault(event);
};
Run Code Online (Sandbox Code Playgroud)

可能的解决方案:

发现这个:http://codeigniter.com/forums/viewthread/102456/

显然它与ajax不能很好地配合.一种解决方案是,如果是ajax调用,则禁止会话更新; 唯一的问题是我们的网站大多是用ajax构建的..

另外,只是将sess_time_to_update降低到非常频繁的状态,并且ajax做得很好.还做了浏览器刷新,它没有超时.不确定为什么会话ID在ajax调用时已经更改,并且浏览器cookie从未更新过.

小智 26

试试这个

<?php
/**
 * ------------------------------------------------------------------------
 * CI Session Class Extension for AJAX calls.
 * ------------------------------------------------------------------------
 *
 * ====- Save as application/libraries/MY_Session.php -====
 */

class MY_Session extends CI_Session {

    // --------------------------------------------------------------------

    /**
     * sess_update()
     *
     * Do not update an existing session on ajax or xajax calls
     *
     * @access    public
     * @return    void
     */
    public function sess_update()
    {
        $CI = get_instance();

        if ( ! $CI->input->is_ajax_request())
        {
            parent::sess_update();
        }
    }

}

// ------------------------------------------------------------------------
/* End of file MY_Session.php */
/* Location: ./application/libraries/MY_Session.php */
Run Code Online (Sandbox Code Playgroud)

问题出在会话类的sess_update函数中,它在X秒后生成一个新的session_id.每个页面都有一个session_id,如果session_id在进行ajax调用之前到期,则该调用将失败.

在/ application/libraries /中创建一个名为MY_Session(或您设置的任何前缀)的php文件,将此代码粘贴到那里即可.此函数将覆盖会话类中的sess_update函数,如果该请求是由ajax发出的,则检查每个请求,跳过sess_update函数.

将sess_expiration设置为更高的值是个坏主意.这是一项安全功能,可以保护您免受会话障碍

PD:我的英语不是很流利,如果你不明白的话,请告诉我.

  • **警告.**在将CI实例分配给变量时使用`=&`而不是`=`.通过引用分配允许您使用原始CodeIgniter对象而不是创建它的副本.鉴于会话以高频率使用,目前这是一个记忆困难. (13认同)

Jor*_*eno 5

在它被合并到稳定分支之前,解决方案(最终!)是使用Areson的提交245bef5与数据库模式相结合:

CREATE TABLE IF NOT EXISTS  `ci_sessions` (
    session_id varchar(40) DEFAULT '0' NOT NULL,
    ip_address varchar(45) DEFAULT '0' NOT NULL,
    user_agent varchar(120) NOT NULL,
    last_activity int(10) unsigned DEFAULT 0 NOT NULL,
    user_data text NOT NULL,
    prevent_update int(10) DEFAULT NULL,
    PRIMARY KEY (session_id),
    KEY `last_activity_idx` (`last_activity`)
);
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请从上到下阅读1283条评论.


Fra*_*nas 3

我们遇到了这个问题,这是由于 config.php 中的 sess_time_to_update 参数造成的。CI 使用它来将会话 ID 更新为新的。如果更改发生在 ajax 调用中,CI 会发送一个新的 cookie 来告诉浏览器新的会话 ID。不幸的是,浏览器似乎会忽略这个 cookie 并保留旧的会话 ID。

我们通过在配置中将 sess_time_to_update 设置为 sess_expiration 来修复此问题。

$config['sess_time_to_update'] = $config['sess_expiration']; 
Run Code Online (Sandbox Code Playgroud)