关键词:
【中文标题】通过后处理上传进度【英文标题】:upload progress with post processing 【发布时间】:2015-02-25 17:24:30 【问题描述】:我有一个上传表单,用户可以在其中上传文件。上传完成后,对文件进行后处理,有时上传完成后处理需要 10-15 秒。
上传完成后,进度条为 100%,但如何检测文件何时完成,因此您可以在文件处理时向用户显示“请稍候”标志。用户可能会认为浏览器已冻结 og 崩溃,因为进度条处于 100%,但没有发生任何事情..
首选纯 HTML5+javascript 的客户端解决方案,但不是必须的:)
【问题讨论】:
也许是后期处理的第二个进度条? 如果你想控制上传的各个方面,比如你想知道上传多少,上传多少等等,你可以看看resumablejs.com。这个 js 库甚至允许您恢复上传。这使您可以完全控制上传。但是有一个小问题,您还需要在后端进行一些配置。上传后,您可以使用 ajax 进行轮询或使用 node.js 显示后端发生的实时进度。 如果您使用 PHP 作为服务器脚本,那么最好使用 APC 模块。使用它,您可以异步更新进度。 能否请您将处理部分说得更清楚一些。我没有看到任何代码示例,也无法猜测您是如何处理上传的。 【参考方案1】:试试
html
<progress min="0" max="10000"></progress>
<output for="progress"></output>
<output for="progress"></output>
<br />
<table id="results"></table>
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 = $("<img />",
"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 ! <br />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(
$("<tr />",
"html": $("<td />",
"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/
【讨论】:
我正在尝试找出您的代码.. 但不是在 HTTP 请求完成时首先触发 jquery ajax 请求(承诺)上的.then()
吗?
@clarkk 你是对的。第一个 then
在 request
内返回对第二个 then
的响应,其中 process
在第二个 then
内返回一个 promise
。有三个.then
调用; 1)处理文件上传,根据file
length
设置progress
,返回响应第二个.then
; 2) 处理来自$.ajax
的响应,在请求可能延迟 10-15 秒后; 3) 完成progress
处理。在实际 file
上传时,arr.length
将是 files[0].size
。包含变量 setTimeout
部分以模拟 OP 中描述的“10-15 秒延迟”。【参考方案2】:
由于您有进度条来显示表单过程要在处理过程中添加更多细节,您可以添加如下图所示
它将向用户显示您的表单仍在处理中create your custom image here
这可能对用户有所帮助 - 浏览器尚未冻结。
【讨论】:
【参考方案3】:我为此使用了自定义上传小部件。在服务器端,当客户端请求更新时,我会向客户端发送以下信息:接收到的文件百分比加上状态消息。通过消息,我可以提供额外的反馈,例如正在执行后处理的哪个步骤或显示错误。
【讨论】:
【参考方案4】:我正在使用一个名为 pekeupload 的 jquery 插件 它体积小,易于实现和定制
http://plugins.jquery.com/pekeUpload/ https://github.com/pekebyte/pekeUpload
希望对你有帮助
最好的
【讨论】:
【参考方案5】: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
<div class="progress">
<div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
</div>
</div>
服务器端进程 - 使用 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;
【讨论】:
【参考方案6】:无论服务器/客户端技术如何,您都可以朝两个方向发展:
1。首先是线性处理(这是你目前的方式)
将服务器上的文件从临时发送回显移动到用户后,例如“文件已成功上传。正在处理...”或仅在 JS 中,您可以在上传完成事件时显示消息而无需来自服务器的任何信息或进行另一个 ajax 调用检查......,真的,有很多类似的方法......重点是上传服务器继续文件处理后(例如刚刚上传的PDF或其他文件的OCR 30页),用户必须等待服务器完成处理. 这很奇怪,因为如果很少有用户同时上传文件,那么所有内容都会同时处理,并且您的服务器将 100% 快速运行......所以这让我想到了
2。使用作业/消息队列
文件上传后,将文件作业放入队列中,并通知用户您将在处理完成时向他发送邮件(或任何通知用户的方式)(例如当您将文件上传到 issuu 时)。这种方式处理上传的文件(可能在另一台机器上;))一个接一个地完成,用户不必等待文件处理完成......这是首选方式。
对于作业/消息队列,您可以使用:
beanstalked RabbitMQ, 别的东西两者都适用于 Java、.NET、Ruby、Python、PHP、Perl、C/C++、Erlang、Node.js,等等……
祝你好运:)
【讨论】:
通过 HTTPS PUT 上传,无需后端脚本处理程序
】通过HTTPSPUT上传,无需后端脚本处理程序【英文标题】:UploadviaHTTPSPUTwithoutback-endscripthandler【发布时间】:2016-07-0503:24:09【问题描述】:有没有办法通过PUT方法将文件上传到https服务器,而无需服务器端脚本来处理请求?我配... 查看详情
关于处理上传图片的问题
主要实现用户选择好照片后,一张一张上传,显示上传进度并且上传完服务器后显示图片//相册选的图片-(void)imagePickerController:(TZImagePickerController*)pickerdidFinishPickingPhotos:(NSArray<UIImage*>*)photossourceAssets:(NSArray*)assetsisSelect 查看详情
如何在ajax调用中获取文件上传进度状态?
...xcall?【发布时间】:2020-04-0408:36:44【问题描述】:我正在通过ajax上传多个文件,我需要在其中保留一个进度条。只有在所有过程完成后我才能获得进度完成状态,所以我需要在上传过程中保持进度条显示状态。在这里,当我单... 查看详情
iCloud 上传进度和密钥
...iCloud上。在将文件标记为普遍存在后,我有一个方法可以通过NSMetadataQuery定期检查文件的状态。当我得到结果时,我使用这些键来获取文件的状态:NSNumber*isUploaded=[ 查看详情
htmljs通过进度条上传文件(代码片段)
通过 HTTP 表单上传文件,通过 MultipartEntityBuilder,带有进度条
】通过HTTP表单上传文件,通过MultipartEntityBuilder,带有进度条【英文标题】:UploadafilethroughanHTTPform,viaMultipartEntityBuilder,withaprogressbar【发布时间】:2013-09-2815:31:17【问题描述】:短版-org.apache...MultipartEntity已弃用,其升级版Multipart... 查看详情
如何通过 ASP.NET MVC 上传文件并显示进度条?
】如何通过ASP.NETMVC上传文件并显示进度条?【英文标题】:HowcanIuploadafileviaASP.NETMVCandshowaprogressbar?【发布时间】:2010-11-0122:56:22【问题描述】:我希望允许用户在我的ASP.NETMVC应用程序中浏览文件并将其上传到服务器。如果可能... 查看详情
进度回顾
...站静态化6、签到功能,看似简单,有点头痛7、消息列表处理8、最头痛的是推广资源问题,待网站运作后慢慢完善 图片上传居然实现不了,暂时只输入文字吧。签到功能刚实现如下,接下来主要是界面优化了。 查看详情
使用 NodeJS REST API 通过 Google Cloud Storage 获取文件上传进度
】使用NodeJSRESTAPI通过GoogleCloudStorage获取文件上传进度【英文标题】:GetfileuploadingprogresswithGoogleCloudStorageusingNodeJSRESTAPI【发布时间】:2017-10-1406:55:32【问题描述】:我正在使用@google-cloud/storagenpm包从NodeJS上传文件。它正在成功将... 查看详情
uploadifive.js怎么去掉进度条
参考技术AUploadify中上传完毕会默认保留进度条并显示100%,前提设置removeCompleted为false,而UploadiFive中上传完毕后进度条自动消失 参考技术BUploadify中上传完毕会默认保留进度条并显示100%,前提设置removeCompleted为false,而UploadiFive... 查看详情
取消表单文件上传提交
...钮。我的网站在Django上运行。我使用不带Ajax的提交按钮通过正常方式提交表单,但我使用jQuery显示上传进度条,因此我使用jQuery输入提交事件以显示进度。有没有办法用jQuery或其他解决方案取消这个提交?我 查看详情
如何在 Alamofire 4.0 中添加带有上传进度百分比的标签的进度条
...【发布时间】:2016-12-3112:01:18【问题描述】:我正在尝试通过Alamofire4.0将视频上传到服务器,我想添加进度条以显示上传过程中上传过程的百分比,我如何通过与Alamofire上传 查看详情
多个图像上传进度问题
...。当我在最后一张上传完成之前拍摄了多张图片时,它会通过随机显示各种上传进度数字来干 查看详情
网页大文件分片上传处理
...原理。断点续传要求本地要记录每一片的上传的状态,我通过三个状态进行了标记(wait loading finish),当网络中断,再次连接后,从断点处进行上传。服务器通过文件名、总片数判断该文件是否已全部上传完成。 &nbs... 查看详情
获取分段上传 Alamofire 5 的上传进度
】获取分段上传Alamofire5的上传进度【英文标题】:GetuploadprogressformultipartuploadAlamofire5【发布时间】:2020-06-1508:00:01【问题描述】:在Alamofire5之前,我们可以使用uploadRequest的encodingReesult来获取uploadProgress。但是现在将Alamofire上传... 查看详情
如何使用 Spring 响应式通过增量进度更新逐个处理每个产品?
】如何使用Spring响应式通过增量进度更新逐个处理每个产品?【英文标题】:HowtoprocesseachproductonebyonewithincrementalprogressupdateusingSpringreactive?【发布时间】:2019-11-0404:38:33【问题描述】:我需要有关SpringReactive的帮助,其中休息调... 查看详情
上传进度指示器以获取?
...声明:进度事件是一项高级功能,目前无法获取。您可以通过查看Content-Length标头并使用传递流来监控接收到的字节来创建自己的 查看详情
oss上传文件进度条展示
...。在此以上传视频为例,自定义监听监听文件上传进度,通过将字节数和总字节数之间比例写入session中返回给前端进行进度展示。 privatestaticStringendpoint="http://oss-cn-beijing.aliyuncs.com";& 查看详情