Lio*_*ing 9 javascript php ajax curl progress-bar
我要做的是将文件/文件信息upload.php上传到使用ajax,然后通过curl将相同的信息再次上传到远程服务器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;
}
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
PHP:(remoteUpload.php)
if (move_uploaded_file($_FILES['fileupload']['tmp_name'], "files/" . $_FILES['fileupload']['name']))
echo "The file has been uploaded.";
else
echo "error";
Run Code Online (Sandbox Code Playgroud)
您可以在表单中的“第一步”高地完成运行后向progressCallback()服务器$_SESSION发出请求以获取并显示第二个进度条(或加载第一个进度条直到 50% 并继续加载第二个 50%),然后从 js 端保存到它完成通话$progresssetIntevral(/*ajax*/)ajax$_SESSION['progress]clearInterval()
详细解答
说明:我们将按照以下逻辑计算进度。如果我们一次上传了 5 个文件(在您的情况下似乎上传的是多个文件),那么我们将在一个文件curl 提交期间100%除以5并增加25%进度,为此您需要进行以下 5 项修改
1)如果没有完成,请调用上面session_start()的某个地方upload.php
2)保存到会话总文件数和当前处理文件索引
// 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
}
Run Code Online (Sandbox Code Playgroud)
3)以格式保存progressCallback函数当前进度号0-100
function progressCallback($dltotal, $dlnow, $ultotal, $ulnow) {
...
$_SESSION['UP_current_progress'] = $progress;
}
Run Code Online (Sandbox Code Playgroud)
4)创建新的getUploadProgress.php并从会话返回 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'],
) );
Run Code Online (Sandbox Code Playgroud)
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);
}
};
Run Code Online (Sandbox Code Playgroud)
注意:在使用此示例代码期间,当然需要进行额外的rounds、JS/PHP functions添加的、变量调整或一些逻辑调整以提高效率,但基本上这是您可以使用的一个选项的逻辑
| 归档时间: |
|
| 查看次数: |
2065 次 |
| 最近记录: |