我正在对一个写请求参数到文件的php文件进行一系列连续(递归)的ajax请求:
make_ajax(s)
{
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function()
{
if(this.readyState == 4 && this.status == 200)
{
if(s>0)
make_ajax(s-1)
}
};
xhr.open('POST','write.php?s='+s+'&string=somelongstring',true);//url + async/sync
...
xhr.send(null);
}
make_ajax(15);//start request
write.php:
file_put_contents('test.txt',$_GET['s']);
似乎服务器在关闭text.txt文件之前就返回了ajax请求,所以由递归发送的下一个ajax请求会收到访问被拒绝的错误,因为似乎文件仍然被上一个ajax请求打开(即使它已经返回)?我甚至使用async=false测试了这个脚本,但我得到了相同的错误?如何避免php脚本在关闭文件之前返回?
注意:我没有使用会话,我只是将数据发送到服务器以保存在文件中。
注意2:这里我做了一个简单的例子,在实际中我使用这种方法通过ajax和mozSlice方法上传文件块。完整代码:
function uploadFileXhr(o,start_byte)
{
var total=o.size;
var chunk;
var peice=1024 * 1024;//bytes to upload at once
var end_byte=start_byte+peice;
var peice_count=end_byte/peice;
$('#debug').html(peice_count);
var is_last=(total-end_byte<=0)?1:0;
chunk=o.mozSlice(start_byte, end_byte);
var xhr = new XMLHttpRequest();//prepare xhr for upload
xhr.onreadystatechange=function()
{
if(this.readyState == 4 && this.status == 200)
{
if(is_last==0)
{
uploadFileXhr(o,end_byte);
}
}
};
xhr.open('POST','upload.php',true);//url + async/sync
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');//header
xhr.setRequestHeader('Content-Type', 'multipart/form-data');//type for upload
xhr.send(chunk);//send request of file
}
uploadFileXhr(file_input,0);//start recrusive call
upload.php:
$flag =($_GET['start']==0) ? 0:FILE_APPEND;
file_put_contents($remotePath.$add.$file_name, file_get_contents('php://input'),$flag);
注意3:实际上,我找到了一个解决方法来避免这个错误,在upload.php脚本中:
$flag =($_GET['start']==0) ? 0:FILE_APPEND;
$file_part=file_get_contents('php://input');
while(@file_put_contents($remotePath.$add.$file_name, $file_part,$flag)===FALSE)
{
usleep(50);
}
但我仍然无法解释为什么在第一种情况下会出现访问被拒绝的错误,所以等待评论!
file_put_contents()
是阻塞的。脚本在文件关闭之前不会完成。 - ridxhr.open(...,...,false);
。 - DaveRandom