jquery ajax文件上传,多文件上传,显示进度条,取消上传操作

最近公司需求,实现文件上传,多文件上传,显示进度条。
首先可以使用各种文件上传的插件,但是,上传显示的列表样式不太好控制,一般都是弹框显示列表或者直接在某个div 中显示列表,如果需求对样式不太有要求,完全可以使用,这里就不再多说。
但是如果要求必须在页面的某一块显示,并且显示列表的样式就需要自己写了,这里不使用插件,直接使用jquery ajax进行文件上传,多文件上传,并且要显示进度条,支持取消上传功能;
基本思路是,
1.在点击选择文件时,首先拼接显示列表,并且显示进度条等
2.根据文件名称不同,对每一条显示数据进行编号,(这里可以使用MD5工具对文件名进行处理)
3.执行文件上传操作,上传完成后清除不需要显示的样式
4.关于重新上传,首先要对上传失败的文件进行记录,把它放到一个 formData 中,再次重新上传时,通过文件名 从中进行读取,然后执行上传方法即可。

代码如下:

    var strName=$(_this).parent().attr("data-name");

    //取出当前的file
    var files = formAll.getAll("file");
    var formdd =new FormData();
    formdd.append("classify_id", $("#classify_id").val());
    formdd.append("dir", $("#currentDir").val());
    var labels = $("input[name^='labelId_']:checked");
    for (var i = 0; i < labels.length; i++) {
      formdd.append("labelIdList", $(labels[i]).val());
    }
    var tops = $("input[name^='topic_id']:checked");
    for (var i = 0; i < tops.length; i++) {
      formdd.append("topic_id", $(tops[i]).val());
    }
	//这边是比对 根据文件名 比对出需要重新上传的文件
    for(var i in files){
      if(files[i].name.split(".")[0]==strName){
        formdd.append("file",files[i]) ;
        break;
      }
    }

5.针对于多文件上传,我的操作还是通过循环formData里的file,通过ajax异步进行上传,因为这里要求是同时将上传的文件显示在列表上,如果没有页面要求,可以直接将formData中的所有file传到后台,然后后台再循环进行上传操作就可以

6.重点:取消ajax上传操作问题,当只是单个的文件上传时,直接调用 ajax的 .abort() 方法即可,如下:

var requestAjax = null;  
    function startAjax(){  
        //方法就是将XHR对象指向currentAjax,再调用currentAjax的.abort()来中止请求  
        requestAjax = $.ajax({  
               type:'POST',  
               beforeSend:function(){},  
               url:'test.PHP',  
               data:'username=xxx',  
               dataType:'JSON',  
               error:function(){alert('error')},  
               success:function(data){alert(data)}  
        });  
    }  
    function stopAjax(){  
        //如若上一次AJAX请求未完成,则中止请求  
        if(requestAjax ) {requestAjax .abort();}  
    }  

但是当多文件循环上传时,ajax异步同时发起多个请求,这里就不能直接操作 requestAjax .abort(),因为你不知道当前的ajax是哪一个,实现思路是,将每一个ajax请求,放入到一个 map中,map的key就是文件名,值就是当前的这个ajax,读取的时候再根据文件名读取,然后继续调用.abort() 方法即可。

直接上代码:

//这里是上传提交方法
//确定按钮  提交内容数据 和上传的数据
  var form = new FormData();//全局变量可以支持多次选择
  $('#files-open-bottom_sure').click(function() {
    resetFlag=2;
    offFlag=2;
    if ($('#file').val() == '') {
      toastr.warning("请选择文件再上传");
    } else {
      if(form.get('file')==null){
        toastr.warning("请选择文件再上传");
        return false;
      }

		//隐藏弹框
      $("#files_open").hide();
      form.append("classify_id", $("#classify_id").val());
      form.append("dir", $("#currentDir").val());

      formAll.append("classify_id", $("#classify_id").val());
      formAll.append("dir", $("#currentDir").val());

      var labels = $("input[name^='labelId_']:checked");
      for (var i = 0; i < labels.length; i++) {
        form.append("labelIdList", $(labels[i]).val());
        formAll.append("labelIdList", $(labels[i]).val());
      }
      var tops = $("input[name^='topic_id']:checked");
      for (var i = 0; i < tops.length; i++) {
        form.append("topic_id", $(tops[i]).val());
        formAll.append("topic_id", $(tops[i]).val());
      }

      //for (var i = 0; i < $("#file")[0].files.length; i++) {
      //    form.append("file", $("#file")[0].files[i]);
      //}
      //获取form中的file
      var formfile= form.getAll("file");
      //循环提交 循环修改进度条
      for(var i in formfile) {
        form.delete("file");
        form.append("file", formfile[i]);
        formAll.append("file", formfile[i]);
        var vname = formfile[i].name;
        //这里是一个上传方法
        ajaxSubmit(form,vname);
      }

    }
  });


//上传方法
var requestAjax;
  var ajaxList = new Array();
  var map = {};
  function ajaxSubmit(formData,name){
    var strName = name.split(".")[0];

    /*if (strName.indexOf(" ") != -1) {
      toastr.error("上传失败!文件名不能有空格");
      setTimeout("location.reload()",3000);
      return false;
    }*/

    //获取文件的后缀名
    var startIndex = name.lastIndexOf(".");
    var ss =name.substring(startIndex+1, name.length);
    if(ss.trim() !="mp4" && ss.trim() !="docx" && ss.trim() !="doc"&& ss.trim() !="pdf" && ss.trim() !="ppt"&& ss.trim() !="pptx"){
      toastr.error("上传失败!只支持上传,视频格式:Mp4,文档格式:Word、PDF、PPT、pptx");
      form=new FormData();
      zlList.load();
      return false;
    }
    strName=$.md5(strName);
    $('#progress_'+strName+'> div ').css('width','');

    toastr.info("上传中,请稍后!");
    requestAjax = $.ajax({
      url: "<%=request.getContextPath() %>/ps/file/upload.action",
      type: "post",
      data: formData,
      cache: false,
      processData: false,
      contentType: false,
      xhr: function () {
        /*var xhr = new XMLHttpRequest();
        //使用XMLHttpRequest.upload监听上传过程,注册progress事件,打印回调函数中的event事件
        xhr.upload.addEventListener('progress', function (e) {
            debugger
            console.log(e);
            //loaded代表上传了多少
            //total代表总数为多少
            var progressRate = (e.loaded / e.total) * 100 + '%';
            //通过设置进度条的宽度达到效果
            $('#progress_'+strName+'> div ').css('width', progressRate);
        })
        return xhr;*/

        var xhr = $.ajaxSettings.xhr();
        if (xhr.upload) {
          xhr.upload.addEventListener("progress", function (evt) {
            var loaded = evt.loaded;
            var total = evt.total;
            var percent = Math.floor(100*loaded/total);//百分比
            if (percent<=99){
              $('.percent').text(percent+"%");//数显进度
              $('.fail-reroad-progress').css("width",percent+"%");
            }
            var progressRate = Math.floor((loaded / total)* 100) + '%';
            //通过设置进度条的宽度达到效果
            $('#progress_'+strName+'> div ').css('width', progressRate);
            //显示上传数值
            $('#jdNum_'+strName+'').text(progressRate);

          }, false);
          return xhr;
        }
      },
      success: function (data) {
        //$("#files_open").hide();
        //hideMask();
        if (data != "success") {
          //显示重新上传
          $('#progress_text_set_'+strName+'').show();
          //显示删除 隐藏取消
          $('#del_'+strName+'').show();
          $('#off_'+strName+'').hide();


          toastr.error("上传失败!");
          $('.percent').text("上传失败");
          $('.fail-reroad').css("color","red");
          $('.files-open-upright-row-a3').css("color","red");
          form = new FormData();//清空form,避免重复上传
        } else {
          $('#progressBox_'+strName+'').remove();
          //进度条清空 隐藏
          //$('#progress_'+strName+'> div ').css('width','');
          // $('#progress_'+strName+'').hide();
          //隐藏上传数值
          // $('#jdNum_'+strName+'').parent().hide();
          // zlList.load();

          //修改上传列表的height
          $('#subfiles_'+strName+'').find(".m-table-td").eq(0).css("height","55px");

          toastr.success("上传成功!");
          $('.percent').text("100%");
          $('.fail-reroad-progress').css("width","100%");
          form = new FormData();//清空form,避免重复上传
        }
      },
      error: function () {
        if(offFlag!=1){
          toastr.error("上传失败!");
        }
        //显示重新上传
        $('#progress_text_set_'+strName+'').show();
        //显示删除 隐藏取消
        $('#del_'+strName+'').show();
        $('#off_'+strName+'').hide();

        //进度条清空
        // $('.progress > div').css('width','');
        // $('.progress ').hide();
        // hideMask();
        //  zlList.load();
        $('.percent').text("上传失败");
        $('.fail-reroad').css("color","red");
        $('.files-open-upright-row-a3').css("color","red");
        form = new FormData();//清空form,避免重复上传
      }
    });

    map[strName] = requestAjax;
    ajaxList.push(map);
  }


//取消上传  取消标志
  var offFlag;
  function offUpload(keyname){
    offFlag=1;
    if(resetFlag!=1){
      map[keyname].abort();
    }else{
      resetupload.abort();
    }
  }

你可能感兴趣的:(js)