【问题标题】:Refresh page during ajax call is destroying the php sessionajax 调用期间刷新页面正在破坏 php 会话
【发布时间】:2016-06-21 13:18:00
【问题描述】:

当我进行 AJAX 调用时,我需要等待它的响应才能显示给用户。

function update() {
    if (HttpReq.readyState == 4) {
        if (HttpReq.status == 200) {
            var div = document.getElementById('divAjax');
            div.innerHTML = HttpReq.responseText;
        } else {
            alert("Error: " + HttpReq.statusText);
        }
    }
}

HttpReq = new XMLHttpRequest();
HttpReq.onreadystatechange = update;
HttpReq.open('GET', 'some_url.php', true);
HttpReq.send(null);

但是,如果用户在响应之前按 F5 刷新屏幕,我会丢失我的 $_SESSION 数据,这会自动将用户注销。

这是一种常见的行为,还是我的代码有问题? (我使用的是安全会话加载器,也许问题就在那里。如果需要,我可以发布代码。)

问题并不完全在于 F5,它是在某些特殊情况下发生的事情,这只是我找到的重现该行为的最简单方法。

代码:

// index.php
ini_set('session.gc_maxlifetime', 3600);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
session_save_path('/var/www/html/plantas/sessions');
sec_session_start(); // this line called in every other .php file

// functions.php
function sec_session_start() {
    $session_name = 'sec_session_id';   // Set a custom session name
    $secure = SECURE;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location: ../html/plantas/error.php?err=Could not initiate a safe session (ini_set)");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"],
        $cookieParams["domain"],
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);

    session_start();                // Start the PHP session
    session_regenerate_id(true);
}

// every other .php file begin with
include_once '../../includes/db_connect.php';
include_once '../../includes/functions.php';
sec_session_start();

解决方案

剪掉

session_regenerate_id(true);

来自functions.php并在之后插入

// index.php
ini_set('session.gc_maxlifetime', 3600);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
session_save_path('/var/www/html/plantas/sessions');
sec_session_start(); // this line called in every other .php file

【问题讨论】:

  • 是的,最好显示所有涉及的代码。
  • some_url.php 检查此请求中的内容
  • 在正常情况下,会话仅在您关闭浏览器时关闭,除非您检查后退按钮和刷新,这似乎不适用于您。所以是的,分享涉及的代码会有所帮助。
  • 添加了一些代码。 @YehiaAwad,我有几十个 php 文件,其中任何一个都可能给出类似的错误。
  • @akmsharma 实际上,我没有返回按钮或刷新的代码。

标签: javascript php ajax session


【解决方案1】:

session_regenerate_id() 表示每次完整页面加载或 Ajax 请求调用 URL 时都会重命名会话。 但是由于http_only=true,在 Ajax 请求期间会话 cookie 不会被覆盖。 并且由于session_regenerate_id(true) 删除了旧会话,如果在两个完整页面加载之间存在Ajax 调用,则会话标识符会被客户端丢失。

您不应在 Ajax 调用期间使用session_regenerate_id($anything)

【讨论】:

    【解决方案2】:

    根据代码,你有这行代码session_regenerate_id(true);,这正是你不想要的,但是为什么?

    根据documentation

    session_regenerate_id() 会将当前会话 id 替换为新的 一、保留当前会话信息。

    但这不应该删除您的旧会话,那么发生了什么? 实际上,您将bool 参数设置为true(默认为false),这告诉预处理器删除旧会话并用新会话替换它

    bool session_regenerate_id ([ bool $delete_old_session = false ] )

    所以解决您的问题的方法是删除本机方法中的true 参数并保持原样:session_regenerate_id();

    编辑

    如果此请求仅用于 Ajax,则启动或使用会话是多余的。除非您在发出请求之前检查用户身份。

    【讨论】:

    • 在这种情况下,单个用户有多个会话。这听起来不像罗德里戈想要的。看来他很想保护自己的踪迹。
    • @CWürtz 如果他正在使用重新生成会话,这意味着他出于某种目的需要它,也许这个函数在另一个不是 ajax 的地方使用它取决于他的代码架构而且更多具体来说,如果它只是ajax,那么他根本不应该使用会话功能并删除代码中的其余部分)
    • 是的。在这种情况下,他会阅读如何使用会话令牌(客户端和服务器端)。
    • 会话令牌用于 csrf 保护和保持特定会话直到它达到所需的目标我看不到这两个对 ajax 有任何用途
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 2019-04-25
    • 2017-08-30
    • 2013-12-22
    • 2010-10-05
    • 2012-10-16
    相关资源
    最近更新 更多