我有一个简单的AJAX请求到PHP文件。一旦PHP脚本到达某一点,我希望响应完成并发送回客户端。之后我仍然需要PHP脚本来运行一个最多需要15秒的函数。目前,浏览器在处理响应之前等待整个PHP脚本完成。我曾尝试使用flush();
或ob_flush();
,但在发送响应之前,它仍然等待PHP脚本完成运行。
JQuery代码:
jQuery.ajax({
url: "../phpFile.php",
data: formdata,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (data) {
data = $.parseJSON(data);
if(data.success){
window.location = "../public/dashboard.php";
}
}
});
PHP代码:
if ($script_reached_this_point) {
// ob_start();
echo json_encode(['success' => 'Ticket added']);
//flush();
// ob_end_flush();
run_15_second_function();
}
答案 0 :(得分:2)
我通过使用2个PHP脚本解决了类似的问题。我们称他们为receiver.php
和worker.php
。过程如下:
receiver.php
receiver.php
在辅助连接中调用worker.php
,向其传递作业说明并等待第一行响应。worker.php
到达,receiver.php
就会关闭该连接receiver.php
立即返回对AJAX的响应并退出。worker.php
继续在后台工作<强> receiver.php 强>
//data to be forwarded to worker.php
$postData = json_encode($_POST);
// headers for the connection to worker.php
$headers = "POST /path/to/worker.php HTTP/1.1".PHP_EOL;
$headers .= "Host: localhost".PHP_EOL;
$headers .= "Content-Length: ".strlen($postData).PHP_EOL;
$headers .= "Content-Encoding: none".PHP_EOL;
$headers .= "Content-Type: application/json".PHP_EOL;
// create socket to the local webserver for calling background script
$socketToWorker = fsockopen("localhost", 80, $errno, $err_msg);
if(!$socketToWorker) die("fsockopen error #$errno: $err_msg");
// Make the request and send the POST data
fwrite($socketToWorker, $headers.PHP_EOL.$postData);
//read until the 1st packet is returned, then stop. 8192 is arbitrary
//but needs to be greater than the expected response from worker.php
$data = fread($socketToWorker,8192);
fclose($socketToWorker);
//send response to browser (work still ongoing in background)
if($data==='OK') echo "Success";
else echo "Background work failed. Error: $data";
<强> worker.php 强>
//parse input from receiver.php
$postData = json_decode(file_get_contents('php://input'),true);
//TODO: validate $postData.
// If data is valid, set below to 'OK' to accept the job
$acceptJob = 'OK'; //replace with an error message to reject the job
ob_start(); //start the buffer
echo $acceptJob; //this is what receiver.php will see
//set headers for the response to receiver.php
header("Content-Encoding: none");
header('Connection: close');
header('Content-Length: '.ob_get_length() );
// flush buffer. Will cause receiver.php to receive data and disconnect
ob_end_flush(); ob_flush(); flush();
if($acceptJob!=='OK') exit;
##################### START THE JOB HERE #####################
set_time_limit(60); //only needed if you expect job to last more than 30 secs
run_15_second_function();