发送 ajax 请求时避免会话超时重置

Avoid session timeout reset when sending ajax request

如果 post 请求通过 ajax 到达特定控制器功能,是否可以告诉 codeigniter 跳过会话超时重置。我在用户登录仪表板中经常 ajax 调用以检查某些内容,但这些调用使会话保持活动状态,因此即使用户保持非活动状态 10 分钟(sess_expiration 时间)会话也不会被终止,它们仍然永远保持登录状态。

如果(且仅当)您的 Ajax 调用完全 session-agnostic(即不需要登录 运行,则不需要来自用户的任何会话数据等)您可以从单独的 ajax-specific 控制器提供 Ajax 请求,然后在使用该特定控制器时禁止会话库自动加载。

如果 ajax 调用需要登录用户,那你就不太走运了。

但是,如果您满足这些条件,请在 application/config/autoload.php 中找到 $autoload['libraries] 部分并使用这个肮脏的技巧:

// Here, an array with the libraries you want/need to be loaded on every controller
$autoload['libraries'] = array('form_validation');

// Dirty hack to avoid loading the session library on controllers that don't use session data and don't require the user to have an active session
$CI =& get_instance();
// uncomment the one that fits you better
// Alternative 1: you only have a single controller that doesn't need the session library
// if ($CI->router->fetch_class() != 'dmz') array_push($autoload['libraries'], 'session');
// END alternative 1

// Alternative 2: you have more than one controller that doesn't need the session library
// if (array_search($CI->router->fetch_class(), array('dmz', 'moredmz')) === false) array_push($autoload['libraries'], 'session');
// END alternative 2

上面代码中,dmzmoredmz是我假想的两个要求session库不加载的controller名称。只要不使用这些,session 库就会被推入自动加载并加载。否则,session 库将被忽略。

我实际上在我的一个网站上有这个 运行ning 以允许从我的负载均衡器到 运行 的健康检查(每 5 秒一次在每个应用程序服务器上,从两个主loadbalancer 及其备份)并用无用的数据填满我的会话 table 并且工作起来非常棒。

不确定您使用的 CI 是哪个版本,但上面的代码是在 CI 3.1.11.

上测试的

现在,正如您所说的 Ajax 调用需要会话驱动程序,解决此问题的唯一方法是稍微弄乱会话驱动程序本身。在 3.1.11 中,会话驱动程序位于 system/libraries/Session/Session.php 中,您需要更改的部分是构造函数方法的最后部分(从第 160 行开始查看)。对于这个例子,我假设你的 Ajax 调用是由一个名为“Ajax”

的特定控制器处理的
// This is from line 160 onwards
elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id())
        {
            $CI =& get_instance();
            $new_validity = ($CI->router->fetch_class() !== 'ajax') ? time() + $this->_config['cookie_lifetime'] : $_SESSION['__ci_last_regenerate'] + $this->_config['cookie_lifetime'];

            setcookie(
                $this->_config['cookie_name'],
                session_id(),
                (empty($this->_config['cookie_lifetime']) ? 0 : $new_validity),
                $this->_config['cookie_path'],
                $this->_config['cookie_domain'],
                $this->_config['cookie_secure'],
                TRUE
            );
        }

        $this->_ci_init_vars();

        log_message('info', "Session: Class initialized using '".$this->_driver."' driver.");

简而言之,这个例子(还没有测试,所以请在部署之前测试,它可能有一个或两个错字)将首先实例化 CI 核心并从 Router 获取控制器名称.如果它是常规控制器,它将确定新的 cookie 有效性为“现在加上来自配置的 cookie 有效性”。如果是 ajax 控制器,则 cookie 有效性将与当前有效性相同(上次重新生成时间加上 cookie 有效性.. 必须重申它,因为三元运算符需要它)

之后,setcookie 被修改为使用 pre-computed cookie 有效性,具体取决于 _config['cookie_lifetime'] 值是什么。