我认为你的问题与会话有关.
当脚本具有打开的会话时,它会锁定会话文件.这意味着任何使用相同会话ID的后续请求都将排队,直到第一个脚本释放它对会话文件的锁定为止.您可以使用session_write_close()强制执行此操作 – 但这不会对您有所帮助,因为您尝试与会话文件共享进度信息,因此后脚本需要保持会话数据的开放性和可写性.
您需要提出另一种在帖子和进度脚本之间共享数据的方法 – 如果post在整个执行过程中打开了会话数据,那么在post完成执行之后,进程将永远无法访问会话数据.也许您可以使用会话ID创建一个临时文件,该文件具有写访问权限,您可以在其中放置进度指示器数据.进度可以检查文件并返回该数据. IPC(进程间通信)有很多选择 – 这不是一个特别漂亮的选项,但它确实具有最大的可移植性.
作为旁注 – 请不要将字符串传递给setInterval(),传递函数.所以你的行应该真正读到:
var progress = setInterval(ask, 500);
但是 – 在ask()ajax函数的成功/错误处理程序中使用setTimeout()会更好.这是因为通过使用setInterval(),无论前一个请求的状态如何,都将启动一个新请求.在开始下一个请求之前等待上一个请求完成会更有效.所以我会做更像这样的事情:
// We'll set this to true when the initail POST request is complete, so we
// can easily know when to stop polling the server for progress updates
var postComplete = false;
var ask = function() {
var time = new Date().getTime();
$.ajax({
type: 'get',
url: '/url/to/progress' + '?time=' + time,
success: function(data) {
$("#progress").html(data);
if (!postComplete)
setTimeout(ask, 500);
}
},
error: function() {
// We need an error handler as well, to ensure another attempt gets scheduled
if (!postComplete)
setTimeout(ask, 500);
}
}
});
}
$("#test").click(function() {
// Since you only ever call post() once, you don't need a seperate function.
// You can just put all the post() code here.
var time = new Date().getTime();
$.ajax({
type: 'post',
url: '/url/to/post' + '?time=' + time,
data: {
"some": "data"
},
success: function(data) {
postComplete = true;
alert(data);
}
error: function() {
postComplete = true;
}
});
if (!postComplete)
setTimeout(ask, 500);
}
});
…虽然这仍然无法解决会话问题.