水一篇。最近群里接了小活,帮忙添加上传进度和速度显示,500块,心里窃喜这不是很简单吗
先调研看看,调研了发现两条路可以走,一是PHP的Session Upload Progress,二是xhr2的progress event。本身我就是做后端的,所以想直接改后端的东西,浏览器兼容问题让人头疼。
PHP 的 Session Upload Progress
参见 https://www.php.net/manual/en/session.upload-progress.php
support PHP5.4.0+
上传图片后,可以通过$_SESSION["upload_progress_123"]
拿到上传信息,包括开始时间,大小(byte),接收大小,是否处理完毕
<?php $_SESSION["upload_progress_123"] = array( "start_time" => 1234567890, // The request time "content_length" => 57343257, // POST content length "bytes_processed" => 453489, // Amount of bytes received and processed "done" => false, // true when the POST handler has finished, successfully or not "files" => array( 0 => array( "field_name" => "file1", // Name of the <input/> field // The following 3 elements equals those in $_FILES "name" => "foo.avi", "tmp_name" => "/tmp/phpxxxxxx", "error" => 0, "done" => true, // True when the POST handler has finished handling this file "start_time" => 1234567890, // When this file has started to be processed "bytes_processed" => 57343250, // Number of bytes received and processed for this file ), // An other file, not finished uploading, in the same request 1 => array( "field_name" => "file2", "name" => "bar.avi", "tmp_name" => NULL, "error" => 0, "done" => false, "start_time" => 1234567899, "bytes_processed" => 54554, ), ) );
测试了下,并不行,翻一下下面用户的留言,发现当你用fastcgi,这是个废特性。。放弃
https://www.php.net/manual/en/session.upload-progress.php#109091
xhr2 的progress event
兼容性参考 https://www.caniuse.com/#feat=xhr2
xhr2的兼容性还是可以的。在2012年的时候主流浏览器已经支持的不错,包括IE10。IE9- 就别考虑了。
// 我这里用的JQuery,撸jq真爽
// 准备formdata数据
var form = $('#form1');
var formData = new FormData(form[0]);
$.ajax({
'type': 'post',
'url': 'url',
'data': formData,
'cache': false,
'processData': false,
'contentType': false,
'xhr': function () {
// 使用原生的xhr对象
var myXhr = $.ajaxSettings.xhr();
// 注册上传progress事件
if (myXhr.upload) {
myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
myXhr.upload.addEventListener('load', function () {
setDefaultProgress('上传完成,后台处理中..');
});
}
return myXhr;
}
}).success(function (res) {
alert(res['msg']);
}).error(function () {
alert('上传失败');
});
});
// 上传进度
var beforeTime = new Date().getTime();
var beforeData = 0;
function progressHandlingFunction (e) {
// 已上传的字节数
var curr = e.loaded;
// 文件总字节数
var total = e.total;
// 进度 百分比 这个很容易
var process= curr / total;
process = Math.floor(process * 10000) / 100
var p = $('#progress_p');
p.text(process + '%');
// 速度 kb/s 这里用简单的物理公式 v = s/t
var afterTime = new Date().getTime();
var diffTime = (afterTime - beforeTime);
beforeTime = afterTime;
var diffData = curr - beforeData ;
beforeData = curr;
if (diffTime !== 0) {
// 这里的换算 byte/ms = (kb * 1024) / (s * 1000) = kb/s * (1024 / 1000)
ve = Math.floor(diffData / diffTime * (1000 / 1024));
// 处理Infinity的情况
if (ve !== Infinity) {}
}
}
最后
发现xhr2的浏览器支持程度还可以啊,并且 fastcgi下的session upload progress实现不了上传进度,遂前端实现之。