PHP 前端

web 上传进度 和 速度显示

2019年7月22日

水一篇。最近群里接了小活,帮忙添加上传进度和速度显示,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实现不了上传进度,遂前端实现之。

发表评论

电子邮件地址不会被公开。 必填项已用*标注