在脚本完成之前返回从php到ajax的响应 [英] return response to from php to ajax before script finishes
问题描述
我有一个简单的AJAX请求到PHP文件。一旦PHP脚本到达某一点,我希望响应完成并发送回客户端。之后我仍然需要PHP脚本来运行一个最多需要15秒的函数。目前,浏览器在处理响应之前等待整个PHP脚本完成。我曾尝试使用 flush();
或 ob_flush();
,但它仍然等待PHP脚本在发送响应之前完成运行。
I have a simple AJAX request that to a PHP file. Once the PHP script reaches a certain point I would like for the response to be completed and sent back to the client. After that I still need the PHP script to run a function that takes up to 15 seconds. Currently the browser waits for the entire PHP script to finish before processing the response. I have tried to use flush();
or ob_flush();
, but it still waited for the PHP script to finish running before sending the response.
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();
}
推荐答案
我解决了有两个PHP脚本的类似问题。我们称之为 receiver.php
和 worker.php
。流程如下:
I solved a similar problem by having 2 PHP scripts. Let's call them receiver.php
and worker.php
. The process is as follows:
- AJAX调用
receiver.php
-
receiver.php
在辅助连接中调用worker.php
,将作业指令传递给它并且等待第一行回复。 - 第一行响应从
worker.php
到达时,receiver.php
关闭该连接 -
receiver.php
立即返回对AJAX的响应退出。 -
worker.php
继续在后台工作
- AJAX calls
receiver.php
receiver.php
callsworker.php
in a secondary connection, passes it the job instructions and waits for the first line of response.- As soon as the first line of response arrives from
worker.php
,receiver.php
closes that connection receiver.php
returns the response to AJAX immediately and exits.worker.php
continues work in the background
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();
这篇关于在脚本完成之前返回从php到ajax的响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!