欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

webuploader上传大文件总结-一字腾云-SegmentFault思否

程序员文章站 2023-09-08 18:37:11
由于业务需要,需要上传大文件,已有的版本无法处理ie版本,经过调研,百度的 webuploader 支持 ie ,而且支持计算md5值,进而可以实现秒传的功能。 大文件上传主要分为...

由于业务需要,需要上传大文件,已有的版本无法处理ie版本,经过调研,百度的 webuploader 支持 ie ,而且支持计算md5值,进而可以实现秒传的功能。

大文件上传主要分为三部分,预上传分块上传合并上传

预上传:计算md5值,同时获取服务器返回的参数,作为分块上传的参数

分块上传:对文件按照固定的大小进行分块,分块后并上传块,其中参数包含预上传计算的md5值,如果上传的分块已经存在,则跳过执行,如果不存在,则执行分块上传。

合并上传:当所有的分块完成上传后,对文件进行合并上传。

其中,用到beforesendfile,afterfilesend这两个监听函数,其中,监听函数beforesendfile,主要是计算md5值,同时进行预上传,用到defered,是为了等待异步执行的结果。uploadbeforesend与beforesendfile对应,uploadbeforesend主要有以下功能:

默认的上传参数,可以扩展此对象来控制上传参数。

可以扩展此对象来控制上传头部。

当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
afterfilesend 是完成最终的大文件合并上传。

代码如下:

var filemd5; //保存文件md5名称
var uploader; //全局对象uploader
var dfsid;
var uploadid;
var rnd = gc.grnd();
var uploadshardsize = parent.gmain.isceph=="1"?5 * 1024 * 1024:4 * 1024 * 1024;
var discusscontent = jquery('#upload_discusscontent');
if (parent.gmain.disktype == 2) {
  discusscontent.parent().show();
}
webuploader.uploader.register({
  "before-send-file" : "beforesendfile", //文件上传之前执行
  "before-send" : "beforesend", //文件块上传之前执行
  "after-send-file" : "aftersendfile", //上传完成之后执行
},
{
//时间点1:所有进行上传之前调用此函数
beforesendfile : function(file) {
    console.log(file);
    var owner = this.owner
    var deferred = webuploader.deferred();
    // 计算文件的唯一标识,用于断点续传和妙传
    (new webuploader.uploader()).md5file(file, 0,
      10 * 1024 * 1024).progress(
      function(percentage) {
        jquery("#" + file.id).find("p.state").text("正在扫描文件") ;
      }).then(
        function(val) {
          filemd5 = val;
          file.filemd5 = filemd5
          jquery("#" + file.id).find("p.state").text("成功获取文件信息");
          // 放行
          var datas = {
          //文件唯一标记
          filemd5 : filemd5,
          disktype: parent.gmain.disktype,
          appfileid: '',
          creatorusn: parent.gmain.groupusn,
          uploadtype: file.chunks == 1 ? 1 : 3,
          comefrom: 11,
          parentid: (parent.gmain.currentfid == -2) ? -1 : parent.gmain.currentfid,
          filesize: file.size,
          groupid: parent.gmain.groupid,
          filename: file.name,
          discusscontent: (parent.gmain.disktype == 2) ? discusscontent.val() : '',
          model: parent.gmain.uploadmodel
        };
        jquery.ajax({
          type : "post",
          url : parent.gconst.ajaxposturl.file + "?func=common:upload&sid="+parent.gmain.sid +"&rnd="+rnd,
          data: json.stringify(datas),
          datatype : "json",
          success : function(response) {
              console.log(response)
              if(response && response.code==='dfs_118'){
                owner.skipfile( file );
                deferred.reject();
                jquery("#" + file.id).find("p.state").text("秒传");
              } else {
                //分块不存在或不完整,重新发送该分块内容
                dfsid = response.var.dfsfileid;
                uploadid = response.var.uploadid;
                deferred.resolve();
              }
        },
        beforesend: function (xmlhttprequest) {
          xmlhttprequest.setrequestheader("content-type", "text/javascript; charset=utf-8");
        }
    });
    });
      return deferred.promise();
},
//每一个分块发送之前执行该操作,检查当前块是否已经上传
beforesend : function(block) {
  var deferred = webuploader.deferred();
  dfsid = dfsid;
  deferred.resolve();
  this.owner.options.formdata = {
  filemd5: filemd5,
  start: block.start
};
  return deferred.promise();
},
aftersendfile : function(file) {
  // 通知合并分块
  console.log(file)
  var comepletedata = {
    disktype: parent.gmain.disktype,
    uploadtype: file.blocks ? file.blocks.length == 1 ? 1 : 3 : 1,
    creatorusn: parent.gmain.groupusn,
    parentid: (parent.gmain.currentfid == -2) ? -1 : parent.gmain.currentfid,
    filesize: file.size,
    groupid: parent.gmain.groupid,
    filename: file.name,
    filemd5: filemd5,
    comefrom: 11,
    uploadid: uploadid,
    dfsfileid: dfsid,
    model: parent.gmain.uploadmodel,
    partcount: file.blocks ? file.blocks.length : 1
  }
  jquery.ajax({
    type : "post",
    url : parent.gconst.ajaxposturl.file+ "?func=common:completeupload&sid="+parent.gmain.sid,
    data: json.stringify(comepletedata),
    datatype: 'json',
    success : function(response) {
    var $li = jquery('#' + file.id);
    $li.find('p.state').text('上传完成');
    jquery("#ctlbtn").addclass('disabled');
    },
    beforesend: function (xmlhttprequest) {
        xmlhttprequest.setrequestheader("content-type", "text/javascript; charset=utf-8");
    }
});
}
});
uploader = webuploader.create({
  swf: '../resource_drive/js/control/fileupload/uploader.swf',
  server: 'service/common/onestfile.do?func=common:onestupload&sid=' + parent.gmain.sid,
  pick:{
    id: '#asd', //这个id是你要点击上传文件按钮的外层p的id
    multiple : true //是否可以批量上传,true可以同时选择多个文件
  },
  auto: true,
  disableglobaldnd: true, //禁用页面拖拽
  chunked: true, // 开启分片上传
  chunksize: uploadshardsize, //分片大小
  chunkretry: 3, //重传次数
  threads: 1, //同时上传进程
  filesizelimit: 2000*1024*1024, //验证文件总大小
  filesinglesizelimit: 2000*1024*1024, //验证单个文件大小
  resize: false,
});
//当文件添加进队列
uploader.on("filequeued", function(file) {
  // filelist
  jquery("#pdialogfileupload").show();
  jquery("#sexwarning").css("display","block");
  jquery(".upfile_ul").css("display","block");
  jquery(".upfile_ul").append("<p id='" + file.id + "'class='fileinfo'><img/><span>" + file.name +
"</span><p class='state'>等待上传...</p><span class='text'><span></p>");
});
//文件上传过程中创建进度条
uploader.on("uploadprogress", function(file, progress){
  var id = jquery("#"+file.id);
  id.find("span.text").text((progress.tofixed(2))*100+"%")
  id.find("p.state").text("上传中...")
  if (progress == 1) {
  id.find("p.state").text("上传完成")
}
});
//发送前填充数据
uploader.on('uploadbeforesend', function( block, data ) {
    // block为分块数据。
    console.log(block);
    console.log(data);
    var deferred = webuploader.deferred();
    // file为分块对应的file对象。
    var file = block.file;
    var filemd5 = file.filemd5;
    // 修改data可以控制发送哪些携带数据。
    // 将存在file对象中的md5数据携带发送过去。
    data.appfileid = "";//md5
    data.filemd5 = filemd5;//md5
    data.filename = data.name;
    data.disktype = parent.gmain.disktype;
    data.uploadtype = block.chunks == 1 ? 1 : 3;
    data.creatorusn = parent.gmain.groupusn;
    data.parentid = (parent.gmain.currentfid == -2) ? -1 : parent.gmain.currentfid;
    data.filesize = data.size;
    data.groupid = parent.gmain.groupid;
    data.model = parent.gmain.uploadmodel;
    data.filerealpath = block.file.source.source.webkitrelativepath;
    data.comefrom = 11;
    data.dfsfileid = dfsid;
    data.blob = data.name;
    if (block.chunks !== 1) {
        data.uploadid = uploadid;
        data.range = block.start + "-" + block.end;
        data.partcount = block.chunks;
        data.partnum = block.chunk + 1;
    }
    data.discusscontent = (parent.gmain.disktype == 2) ? discusscontent.val() : '';
    deferred.resolve();
});
//上传成功
uploader.on("uploadsuccess", function(file) {
    var id = jquery("#"+file.id);
    id.find("p.state").text("已上传")
});
//上传失败
uploader.on('uploaderror', function( file ) {
    var id = jquery("#"+file.id);
    id.find("p.state").text("上传失败")
});
// 上传完成
uploader.on("uploadcomplete", function(file) {
    var id = jquery("#"+file.id);
    id.find("p.state").text("上传完成")
});