我想做的是使用 ajax 将文件/文件信息上传到 upload.php
,然后通过 curl to remoteUpload.php< 将相同的信息再次上传到远程服务器
。最后,在 remoteUpload.php
文件中,我执行文件的实际上传。
在执行第一步时 -> 将文件/文件信息上传到 upload.php
我使用 ajax 显示此步骤的进度条。
但是当执行第二步时 -> 使用 curl 将相同的信息再次上传到远程服务器到 remoteUpload.php
进度条不显示,这是我的问题。
如何通过ajax显示第二步的进度条?
Javascript:
var upload_btn = document.getElementById('upload_file');
var result = document.getElementById('result');
upload_btn.onclick = function () {
var uploadInput = document.getElementsByName('file[]')[0];
if (uploadInput.files.length > 0) {
console.clear();
var ajax = new XMLHttpRequest();
var inputFileData = formData(uploadInput);
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
var json = JSON.parse(ajax.responseText);
result.innerHTML = json.text;
}
};
ajax.upload.addEventListener('progress', function (e) {
result.innerHTML = Math.round(e.loaded / e.total * 100) + "%";
});
ajax.open("post", "upload.php");
ajax.send(inputFileData);
}
};
function formData(inputFileObj) {
var formData = new FormData;
var inputFile = inputFileObj.files;
if (inputFile.length > 0) {
for (i = 0; i < inputFile.length; i++) {
formData.append(inputFileObj.name, inputFile[i]);
}
}
return formData;
}
PHP: (upload.php)
function progressCallback($dltotal, $dlnow, $ultotal, $ulnow) {
static $last;
$progress = @round($ulnow / $ultotal * 100);
if($last < $progress) echo json_encode(array('text' => $progress));
flush();
$last = $progress;
}
if (strtolower($_SERVER['REQUEST_METHOD']) == 'post' && !empty($_FILES)) {
foreach ($_FILES['file']['tmp_name'] as $index => $tmpFileName) {
if ($_FILES['file']['error'][$index] > 0) {
$text = "A file did not uploaded correctly.";
return false;
}
$ch = curl_init("http://serverfiles/remoteUpload.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progressCallback');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('fileupload' => '@' . $tmpFileName));
$text = curl_exec($ch);
}
}
echo json_encode(array('text' => $text));
exit;
PHP: (remoteUpload.php)
if (move_uploaded_file($_FILES['fileupload']['tmp_name'], "files/" . $_FILES['fileupload']['name']))
echo "The file has been uploaded.";
else
echo "error";
最佳答案
您可以在 progressCallback()
中保存到 $_SESSION
您的 $progress
并在“第一步”高地完成运行后从 js 端保存 setIntevral(/*ajax*/)
向服务器发出 ajax
请求获取 $_SESSION['progress]
并显示第二个进度条(或加载第一个进度禁止直到 50% 并继续加载第二个 50%) 在你的表单中,当它完成时调用 clearInterval()
详细答案
说明:我们将按照以下逻辑计算进度。如果我们一次上传了 5 个文件(在您的情况下似乎上传了多个文件),那么我们会将 100%
除以 5
并增加 25%
一个文件 curl 提交过程中的进度,为此您需要进行以下 5 次修改
1) 如果未完成,请在 upload.php
中调用 session_start()
上方的某处
2)保存到 session 总文件数和当前处理文件索引
// Saveing total amount of uploaded files
$_SESSION['UP_total_count'] = count($_FILES['file']);
foreach ($_FILES['file']['tmp_name'] as $index => $tmpFileName) {
...
// Saving current index of uploaded file
$_SESSION['UP_current_index'] = ($index+1);//+1 as it starts from 0
}
3)以0-100
格式保存在progressCallback
函数中当前进度数
function progressCallback($dltotal, $dlnow, $ultotal, $ulnow) {
...
$_SESSION['UP_current_progress'] = $progress;
}
4) 创建新的 getUploadProgress.php
并从 session 中返回 json 编码的进度信息
session_start();
echo json_encode( array(
'total_count' => $_SESSION['UP_total_count'],
'current_index' => $_SESSION['UP_current_index'],
'current_progress' => $_SESSION['UP_current_progress'],
) );
5) 在你的ajax.onreadystatechange
setInteval
函数调用中添加,并在你的js全局变量中定义progressSetInterval
....
var progressSetInterval = null;// Global
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
...
progressSetInterval = setInterval(function(){
$.ajax({
type: "POST",
url: "getUploadProgress.php",
success: function(data){
// Calculating progress based on 100 25 logic explained above
var progressPart = 100 / data['total_count'];
var currProgress =
(data['total_count'] - data['current_index']) * progressPart;
currProgress += (progressPart/100) * data['current_progress'];
// You can display progress somehow, apped to div or show prgoress...
console.log( "Second progress: " + currProgress);
// if currProgress is 100% removing setinterval
if( currProgress >= 100 ){
clearInterval( progressSetInterval );
}
},
dataType: 'json'
});
}, 1000);
}
};
注意:在使用此示例代码期间,当然需要额外的回合
、JS/PHP 函数
添加、变量调整或一些逻辑调整以提高效率,但基本上这是您可以使用的一个选项的逻辑
关于javascript - 如何将curl上传进度发送给ajax显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34313894/