为什么在几乎在执行ajax get请求的同时发布数据时,不会保存php会话数据?
Using a html element for search, my search allows GET and POST requests. I am sending the pressed keys using ajax GET for live search (timeout 750ms) and when the form is submitted, the string is POSTED.
The problem is that new session data is not saved when the ajax request and the form is submitted at the same time.
I found two solutions to this problem but they seem to mask the real problem. First solution is to stop the ajax request when enter is pressed using javascript if ((event.keyCode || event.which) == 13)
and 2nd solution is calling session_write_close()
and session_start()
right after new session data is saved.
Can you explain why some session data is not saved (while others are properly saved during same request) when ajax GET is executed while a html form is in the middle of being posted or else explain the need for calling session_write_close and session_start to make sure session data is saved during critical operations like checking CSRF: generate new token if post is valid and save this in session?
Example code:
PHP Wrapper for storing new key:
public function setCsrfKey($property)
{
$_SESSION['x']['CsrfKey'] = (string) $property;
}
JS code:
$(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);
});
使用html元素进行搜索,我的搜索允许GET和POST请求。 我使用ajax GET发送按键进行实时搜索(超时750毫秒),当提交表单时,字符串为POSTED。 p>
问题是,当ajax请求和表单同时提交时,不会保存新的会话数据。 p>
我找到了两个解决这个问题的方法,但它们似乎掩盖了真正的问题。 第一个解决方案是在使用javascript 你可以解释为什么一些会话数据没有被保存(而其他会话数据在同一个请求中被正确保存)当一个html表单处于发布状态时执行ajax GET或者解释 是否需要调用session_write_close和session_start以确保在关键操作期间保存会话数据,例如检查CSRF:如果post有效则生成新令牌并将其保存在会话中? p>
示例代码: p>
用于存储新密钥的PHP包装器: p>
JS代码: p>
if((event.keyCode || event.which)== 13) code>按下enter时停止ajax请求,第二个解决方案是调用
session_write_close() 保存新会话数据后立即执行code>和
session_start() code>。 p>
public function setCsrfKey($ property)
{
$ _SESSION ['x'] [ 'CsrfKey'] =(string)$ property;
pre>
$(searchBox).on(“keyup”,function( e){
e.stopPropagation();
clearTimeout(ajaxTimeOut);
var keyPressed = e.keyCode || e.which;
var string = $(this).val();
if(string.length&lt; 3){
queueList.clearQueue('ajaxCall');
return;
}
queueList.queue('ajaxCall',function(){
$ .ajax({
url:urlString,
type:'GET',
})。done(function(data){
})。fail(function(){
}); \ n});
ajaxTimeOut = setTimeout(function(){
while(queueList.queue('ajaxCall')。length&gt; 1){
queueList.queue('ajaxCall')。shift();
}
queueList.dequeue('ajaxCall');
},750);
});
code> pre>
div>
PHP writes session data when the script ends unless you tell it otherwise (with session_write_close
). What happens with two simultaneous requests in the same session depends on your session handler...but if the request is allowed to happen, the two requests typically won't see each other's changes to the session, and one's changes will generally get lost.
Calling session_write_close
saves the session so that future requests will use the updated session. It's a bit of a hack; what you have here is a race condition, and there's still a chance of stuff breaking. It'll just be a lot lower the sooner you can commit your changes to the disk/database/whatever. Lower still if you can insert a short delay between requests as well.
Of course, once you've closed the session, it won't get saved when the script ends, so nothing else will get added to it. You have to call session_start()
to reopen it if you want to make further changes to it.