通过后期处理上传进度

我有一个上传表单,用户可以上传文件。 上传完成后,文件将进行后期处理,有时上传完成后处理时间最长为10-15秒。

上传完成后,进度条为100%,但是如何检测文件何时完成,以便在文件处理时向用户显示“请稍候”标志。用户可能会认为浏览器冻结og崩溃,因为进度条是100%但没有发生任何事情..

纯HTML5 + javascript中的客户端解决方案是首选,但不是必须:)

尝试

HTML

   

JS

 var len = arr.length // file length , start = 0 // update progress , outputs = $("output[for=progress]") // notifications , progress = $("progress") , results = $("#results") // post processing // gif spinner , spinner = $("", { "src": "data:image/gif;charset=binary;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5BAAKAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQACgABACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkEAAoAAgAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkEAAoAAwAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkEAAoABAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQACgAFACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQACgAGACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAAKAAcALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" }); // upload file var request = function () { progress.prop("max", len); s = setInterval(function () { progress.prop("value", ++start); outputs.eq(0) .text("uploading file...") }, 1) return $.post("/echo/json/", { json: JSON.stringify(arr) }) .then(function (data) { clearInterval(s) s = null; progress.prop("value", len); outputs.eq(0) .html("upload complete ! 
processing response, please wait...") .next(outputs.eq(1)) .html(spinner); return data }) }; request() .then(function (data) { // do post upload processing stuff var process = function() { var dfd = new $.Deferred(); // processing... t = setTimeout(function () { data.forEach(function (res) { results.append( $("", { "html": $("", { "html": res.value }) })) }); if (results.find("tr").length === len) { dfd.resolve("complete !") } }, 1 + Math.floor(Math.random() * 15000)); return dfd.promise() }; // do stuff when all post processing complete process().then(function(complete) { outputs.eq(0).empty() .next(outputs.eq(1)) .html(complete); clearTimeout(t); t = null; }) });

jsfiddle http://jsfiddle.net/guest271314/d2szrs20/

由于您有进度条来显示表单过程要在处理过程中添加更多细节,您可以添加像下面这样的图像

它将向用户显示您的表单仍在进行中, 在此处创建自定义图像

在此处输入图像描述

这可能有助于用户 – 浏览器尚未冻结。

我正在使用自定义上传小部件。 在服务器端,我在请求更新时向客户端发送以下信息:收到的文件的百分比加上状态消息。 通过该消息,我可以提供额外的反馈,例如后期处理的哪个步骤正在发生或显示错误。

我正在使用一个名为pekeupload的jquery插件它很小,易于实现和自定义

http://plugins.jquery.com/pekeUpload/ https://github.com/pekebyte/pekeUpload

我希望这对你有所帮助

最好

使用Javascript

 function initialize_progress(element) { //initializations! $(element).hide(); $(element).find('.progress-bar').prop('style','width: 0'); } function getProgress(process_id){ var re=new RegExp(process_id+"=[^;]+", "i") //construct RE to search for target name/value pair if (document.cookie.match(re)) //if cookie found return document.cookie.match(re)[0].split("=")[1] //return its value return null } function updateProgress(process_id, element){ var percentage, message, name, failed; $(element).show(); var myIntervalID = setInterval(function() { percentage = getProgress(process_id+"_percentage"); name = getProgress(process_id+"_process_name"); message = getProgress(process_id+"_message"); failed = getProgress(process_id+"_process_failed"); if(percentage) $(element).find('.progress-bar').css('width',percentage+'%').html(percentage+"% "+message); },2000); } //initialize progress bar //initialize_progress(".progress"); $(".upload-button").click(function() { //set listener updateProgress('upload_the_pix', ".progress") var request = $.get( "http://example.com/?progress", function(data) { alert(data); }) .done(function() { alert( "second success" ) }).fail(function() { alert( "error" ); }).always(function() { alert( "finished" ); }); }); 

HTML

  

服务器端进程 – 使用PHP

 class ProcessProgress { protected static $process_id; //current process_id protected static $process_name; //current process name protected static $debug_mode = false; protected static $process_killed = false; /** * Make settings for process setup * @param $settings * Example: * $settings=array( * 'process_id' => 'upload_photos' //must be provided 'process_name' =>'Database Wipe', //tile of this process ); */ public static function settings($settings) { # process id must be set #make array keys properties if( is_array($settings) ){ foreach($settings as $key => $value){ self::$$key = $value; } } if(self::$debug_mode && !self::$process_id) exit('process_id must me provided in settings array'); if(isset($_COOKIE[self::$process_id."_percentage"])){ unset($_COOKIE[self::$process_id."_percentage"]); unset($_COOKIE[self::$process_id."_message"]); unset($_COOKIE[self::$process_id."_process_name"]); unset($_COOKIE[self::$process_id."_process_complete"]); unset($_COOKIE[self::$process_id."_process_failed"]); unset($_COOKIE[self::$process_id."_process_killed"]); } } /** * Kill this process */ public static function kill() { self::$process_killed = true; } /** * @param $percentage * @param $message * @param bool $complete * @param bool $failed * @return bool */ public function setProgress($percentage, $message, $complete=false, $failed=false){ $process_data = array( 'percentage'=>$percentage, 'message' => $message, 'process_id' => self::$process_id, 'process_name' => self::$process_name, 'process_complete' => $complete, 'process_failed' => $failed, 'process_killed' => self::$process_killed, ); setcookie(self::$process_id."_percentage", $percentage, time() + (86400 * 30)); // 86400 = 1 day setcookie(self::$process_id."_message", $message, time() + (86400 * 30)); // 86400 = 1 day setcookie(self::$process_id."_process_name", self::$process_name, time() + (86400 * 30)); // 86400 = 1 day setcookie(self::$process_id."_process_complete", $complete, time() + (86400 * 30)); // 86400 = 1 day setcookie(self::$process_id."_process_failed", $failed, time() + (86400 * 30)); // 86400 = 1 day setcookie(self::$process_id."_process_killed", self::$process_killed, time() + (86400 * 30)); // 86400 = 1 day //verify if(isset($_COOKIE[self::$process_id])) return true; #delay 1 second //sleep(1); } } 

单击按钮时在服务器端使用http://example.com/?progress

  if(isset($_GET['progress'])){ ProcessProgress::settings(array( 'process_id' => 'upload_the_pix', 'process_name' => 'Picture Upload', )); ProcessProgress::setProgress(0, 'Initializing'); for($count=0; $count < 10001; $count++){ switch($count){ case 1000: ProcessProgress::setProgress(10, 'Coping files'); break; case 2000: ProcessProgress::setProgress(20, 'Setting up email'); break; case 3000: ProcessProgress::setProgress(30, 'Looking up things'); break; case 4000: ProcessProgress::setProgress(40, 'Milking your cow'); break; case 5000: ProcessProgress::setProgress(50, 'Syncing contacts'); break; case 6000: ProcessProgress::setProgress(60, 'Updating Facebook profile'); break; case 7000: ProcessProgress::setProgress(70, 'Calling your girl friend'); break; case 8000: ProcessProgress::setProgress(80, 'Making things up'); break; case 9000: ProcessProgress::setProgress(90, 'Feeding your dogs'); break; case 10000: ProcessProgress::setProgress(100, 'Done. Congrats'); break; } } 

}

无论服务器/客户端技术如何,您都可以从两个方向进行:

1.首先进行线性处理(这是你目前的方式)

将服务器上的文件从临时发送回送到用户后,例如“文件已成功上传。正在处理…”或只是在JS中,您可以在没有来自服务器的任何信息的情况下在上传完成事件上显示消息,或者进行另一个ajax调用以进行检查。 ..,真的,有很多方法可以做到这一点..点是上传服务器继续文件处理后(例如OCR 30页刚上传的PDF或其他),用户必须等待服务器完成处理。 这很有气味,因为如果很少有用户同时上传文件,所有内容将同时处理,你的服务器将快速100%…所以这让我想到

2.使用作业/消息队列

上传文档后,将文件作业放入队列,并在处理完成时(例如将文档上载到issuu时)通知用户您将向他发送邮件(或用于通知用户的任何方式)。 这样处理上传文件(可能在另一台机器上;))一个接一个地完成,用户不必等待文件处理完成……这是首选方式。

对于作业/消息队列,您可以使用:

  • beanstalked
  • RabbitMQ ,
  • 别的

两者都适用于Java,.NET,Ruby,Python,PHP,Perl,C / C ++,Erlang,Node.js,什么不…

祝好运 :)