使用Jquery BlueImp上传器

时间:2017-04-05 00:03:37

标签: php jquery file-upload blueimp

我可以通过BlueImp Jquery Uploader插件成功上传大文件(测试高达8GB)。

我的PHP设置是:

upload_max_filesize 8192M
post_max_size 8192M
max_execution_time 200
max_input_time 200
memory_limit 8192M

我遇到的问题是,当大文件(2gb或更大)完成上传时,进度条会挂起100%并需要相当长的时间才能完成"。 除了将文件块拼凑在一起之外,我不确定发生了什么后处理。

我已经尝试调整UploadHandler.php文件中的块大小,并且当增加时(例如从10mb到500mb块)似乎稍微改善了一些东西,但延迟仍然存在。在完全禁用分块上传(0)时似乎没有任何改进,而且我也不确定这样做的潜在后果。

在2gb文件上,延迟大约为20秒,但在4gb文件上,大约需要2分钟。 7gb文件大约需要3-4分钟,有时会超时。这使用户等待,因为进度条此时已达到100%,因此不知道发生了什么。

有没有人能够了解这可能是什么,或者如何对其进行故障排除?我怀疑/ tmp中的文件可能被复制而不是被移动,但据我所知,在php文件中没有这个迹象。

在我的服务器VM上提升CPU和RAM可以稍微改善一些事情,尽管运行" top"在此过程中的命令显示CPU和RAM似乎没有用尽(0-2%,而实际上传时为90-100%)。

非常感谢提前。

3 个答案:

答案 0 :(得分:0)

我不太了解它,我在google上搜索,我发现了一些,我认为它可能对你有帮助。

通常,在服务器或客户端发生异常时会触发“onError”事件。在上述情况下,在服务器本身没有超时之前不会抛出任何异常。

一种可能性是监控上传状态,并在上传事件中设置JavaScript超时或计数器,该事件将在达到时间限制后取消上传。

此处显示所有上传状态和错误代码 - http://help.infragistics.com/NetAdvantage/jQuery/2013.1/CLR4.0?page=igUpload_Using_Client_Side_Events.html

您可以在上传活动中使用“fileStatus”参数监控这些内容。

有助于您的链接

  1. Link1
  2. Link2
  3. Link3

答案 1 :(得分:0)

这可能是什么

jQuery FileUpload注册请求进度事件。这是浏览器向服务器发送数据时的事件,而不是来自服务器的确认事件。浏览器发送和服务器确认接收之间存在延迟。有关这两个事件,请参阅Can onprogress functionality be added to jQuery.ajax() by using xhrFields?。但是,我无法解决这个问题并使用了解决方法,所以我无法完全证实这一假设。

如何排查故障

使用浏览器的调试工具并在代码中设置断点,以了解可用的变量: https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload.js#L372

一旦确定要查看的内容,最好使用console.log打印信息并检查浏览器的控制台输出。

<强>变通

如果您只想查看所有下载是否已完成并向用户显示某些内容仍在进行中,您可能需要查看停止/完成事件,或者还要检查fileupload('active'),请参阅此处: Finish of Multiple file upload

答案 2 :(得分:0)

经过对此问题的大量故障排除和调试后,我发现了我认为的原因,以及更好的解决方法/解决方案。它有点“hacky”(我是一个业余开发者!),所以我愿意接受任何改善这一点的建议,尽管它似乎对我有用。

从客户端上传的文件实际上传到服务器上的此临时位置: /tmp/systemd-private-random-number-httpd.service-random-number/tmp/sess_php-session-ID

在客户端完成上传后,UI进度条达到100%并在服务器处理文件时保持不变。

服务器端的处理涉及将文件从上面的/ tmp位置移动(复制,然后删除)到相关的blueimp位置。 (假设blueimp选项中的“user_dirs”已启用​​/为true,则默认目标为:/ var / www / html / server / php / files / php-session-id /)。

此复制过程可能会花费大量时间,尤其是对于大于2gb或大约2gb的文件。服务器处理完成后,blueimp会触发“fileuploaddone”回调,并且UI会更新为已完成状态。

我的目标是在此时提供一些交互式UI反馈(而不是像其他解决方法一样挂起90%)。我的环境能够进行非常大的上传(10gb +),所以我觉得不能提供任何用户反馈,因为用户认为网站已经崩溃,关闭浏览器等等。 )。

我的解决方法:

我遇到的第一个问题是,在客户端完成文件上传并且服务器处理开始时,似乎没有一个blueimp回调。所以我通过创建一个函数(在main.js中)来解决这个问题,以便在data.loaded匹配data.total之后显示我的自定义“处理div”:

$('#fileupload').bind('fileuploadprogressall', function (e, data) { console.log(data); 
if (data.loaded == data.total) { 
setTimeout(function(){
$("#processwarn").fadeTo(300, 1);
},3000);
}})

位于进度条信息下方的我的自定义div是另一个每隔几秒刷新一次(带有ajax.load)的php页面,并计算当前会话上传文件夹中所有文件的总文件大小(目录总大小)似乎没有提供准确的结果):

// Calculate size of files being processed
$filePath = "/var/www/html/server/php/files/*php-session-id*/";

$total = 0;
$d = new RecursiveIteratorIterator(
  new RecursiveDirectoryIterator($filePath), 
  RecursiveIteratorIterator::SELF_FIRST
);

foreach($d as $file){
  $total += $file->getSize();
}

// Convert to readable format
if ($total >= 1073741824)
{
    $total = number_format($total / 1073741824, 2) . ' GB';
}
elseif ($total >= 1048576)
{
    $total = number_format($total / 1048576, 2) . ' MB';
}
elseif ($total >= 1024)
{
    $total = number_format($total / 1024, 2) . ' KB';
}
elseif ($total > 1)
{
    $total = $total . ' bytes';
}
elseif ($total == 1)
{
    $total = $total . ' byte';
}
else
{
    $total = '0 bytes';
}

// Display spinner gif and size of file currently being processed
echo "<img src=\"img/spinner.gif\" height=\"20px\" width=\"20px\">&nbsp;&nbsp;Please wait, processing files: &nbsp;&nbsp;$total";

结果如下所示:

processing div

编辑:(经过一些工作后) - 改为添加了引导进度条:

bootstrap progress bars

测试中注意到的其他要点:

启用分块(例如设置为1gb(maxChunkSize:1000000000)),问题几乎消失,因为处理时间显着减少到用户,因为“复制”处理发生在分块点(每1gb)在这个例子中)。 当最后的处理发生时,服务器只需要“重新安排”/复制最后剩余的1gb 由于这个原因,我也经历了更快的整体上传时间。 事后看来,对许多人来说,这可能是一个更容易/更有效的解决方案。