当我几乎在执行ajax get请求的同时发布数据时,为什么php会话数据没有保存


Why is php session data not saved when I post data at almost the same time an ajax get request is executed?

使用html元素进行搜索,我的搜索允许GET和POST请求。我使用ajax GET发送按下的键进行实时搜索(超时750ms),当提交表单时,字符串被张贴。

问题是,当ajax请求和表单同时提交时,不会保存新的会话数据。

我找到了两种解决这个问题的方法,但它们似乎掩盖了真正的问题。第一种解决方案是在使用javascript if ((event.keyCode || event.which) == 13)按下回车键时停止ajax请求,而第二种解决方案则是在保存新会话数据后立即调用session_write_close()session_start()

您能解释为什么在发布html表单的过程中执行ajax GET时,某些会话数据未被保存(而其他会话数据在同一请求中正确保存),或者解释是否需要调用session_write_close和session_start以确保在检查CSRF等关键操作期间保存会话数据:如果发布有效,则生成新令牌并将其保存在一场

示例代码:

用于存储新密钥的PHP包装器:

public function setCsrfKey($property)
{
    $_SESSION['x']['CsrfKey'] = (string) $property; 
}

JS代码:

$(searchBox).on("keyup", function(e){
    e.stopPropagation();
    clearTimeout(ajaxTimeOut);
    var keyPressed = e.keyCode || e.which;
    var string = $(this).val();
    if (string.length < 3) {
        queueList.clearQueue('ajaxCall');
        return;
    }
    queueList.queue('ajaxCall', function(){
        $.ajax({
            url: urlString,
            type: 'GET',
        }).done (function( data ) {
        }).fail (function(){
        });
    });
    ajaxTimeOut = setTimeout( function(){
        while (queueList.queue('ajaxCall').length > 1) {
            queueList.queue('ajaxCall').shift();
        }
        queueList.dequeue('ajaxCall');
    }, 750);
});

PHP在脚本结束时写入会话数据,除非您另有指示(使用session_write_close)。同一会话中两个同时请求的情况取决于您的会话处理程序。。。但是,如果允许请求发生,那么这两个请求通常不会看到对方对会话的更改,并且其中一个请求的更改通常会丢失。

调用session_write_close保存会话,以便将来的请求将使用更新的会话。这有点像黑客;你在这里有一个比赛条件,还有机会打破。您越早将更改提交到磁盘/数据库/任何东西,它就会低得多。如果可以在请求之间插入一个短延迟,则更低。

当然,一旦你关闭了会话,脚本结束时就不会保存它,所以不会向它添加任何其他内容。如果你想对它进行进一步的更改,你必须调用session_start()来重新打开它。