在对这个问题进行了多次故障排除和调试之后,我找到了我认为的原因,以及更好的解决方法/解决方案。这有点“hacky”(我是一个业余开发者!),所以我愿意接受任何改进它的建议,尽管它似乎对我有用。
从客户端上传的文件实际上是上传到服务器上的这个临时位置:
/tmp/systemd-private-随机数-httpd.service-随机数/tmp/sess_php-session-ID
在客户端完成上传后,UI 进度条会达到 100%,并在服务器处理文件时保持不变。
服务器端的处理涉及将文件从上述 /tmp 位置移动(复制,然后删除)到相关的 blueimp 位置。 (假设“user_dirs”在 blueimp 选项中启用/为真,默认目标为:/var/www/html/server/php/files/php-session-id/)。
此复制过程可能会花费大量时间,尤其是对于大于 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 是另一个 php 页面,它每隔几秒刷新一次(使用 ajax.load),并计算当前会话上传文件夹中所有文件的总文件大小(目录总大小似乎没有提供准确的结果):
// 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\"> Please wait, processing files: $total";
结果如下所示:
编辑:(经过更多工作)- 添加了引导进度条:
从测试中发现的附加点:
启用分块(例如设置为 1gb (maxChunkSize: 1000000000) )后,问题几乎消失了,因为处理时间对用户来说似乎大大减少了,因为“复制”处理发生在分块点(每 1gb在这个例子中)。
当最终处理发生时,服务器只需“重新分块”/复制最后剩余的 1gb。
因此,我也经历了更快的整体上传时间。
事后看来,这对许多人来说可能是一个更简单/更有效的解决方案。