Jquery Ajax上传多文件获取文件上传进度

我在使用layui文件上传时遇到了个问题,layui只提供了单文件上传,通过定义progress属性接收上传进度。

  ....省略....
 ,progress:function(t,elem,XMLHttpRequest){
 	console.log(t) //文件上传进度
	console.log(elem) //触发事件的Dom元素
	console.log(XmlHttpRequest) //XMLHttpRequest对象
 }
  ....省略....

单从progress回调函数目前返回的数据只能做单文件上传进度条,没有办法,于是动手改了下layui源代码,如下:
|| layui/lay/modeules/upload.js ||

					layui.each(o, function(e, o) {
					var r = new FormData;
			
					r.append(l.field, o), layui.each(l.data, function(e, t) {
						t = "function" == typeof t ? t() : t, r.append(e, t)
					});
					var c = {
						url: l.url,
						type: "post",
						data: r,
						contentType: !1, //此属性必须设定为false
						processData: !1, //此属性必须设定为false
						dataType: "json",
						headers: l.headers || {},
						success: function(t) {
							i++, d(e, t), u()
						},
						error: function() {
							n++, a.msg("请求上传接口出现异常"), m(e), u()
						}
					};
					//如果定义了progress函数,则创建xhr
					"function" == typeof l.progress && (c.xhr = function(x) {
						var e = $.ajaxSettings.xhr();
						return e.upload.addEventListener("progress", function(e) { 
							if (e.lengthComputable) {
								var t = Math.floor(e.loaded / e.total * 100 );
								//改动了此处,将循环的 o 对象传入后调,里面包括了正在上传的文件名,这样通过文件名就可以辨别区分文件上传进度了
								l.progress(t, l.item[0], e, o)
							}
						},false), e
					}), t.ajax(c)
				})
			},

前端可在进度条定义任意属性 值为文件名:

,choose: function(obj){   
	      var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列
	      //读取本地文件 时给进度条定义files属性为文件名
	      obj.preview(function(index, file, result){
	        var tr = $(['<tr id="upload-'+ index +'">'
	          ,'<td>'+ file.name +'</td>'
	          ,'<td><span>等待上传</span><div file="'+file.name+'" class="layui-progress layui-hide" lay-filter="'+index+'" lay-showPercent="true"><div  class="layui-progress-bar layui-bg-green" lay-percent="0%"></div></div></td>'
	          ,'<td>'
	            ,'<button class="layui-btn layui-btn-xs demo-reload layui-hide">重传</button>'
	            ,'<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">删除</button>'
	          ,'</td>'
	        ,'</tr>'].join(''));
	        //单个重传
	        tr.find('.demo-reload').on('click', function(){
	          obj.upload(index, file);
	        });
	        
	        //删除
	        tr.find('.demo-delete').on('click', function(){
	          delete files[index]; //删除对应的文件
	          tr.remove();
	          uploadListIns_{$info["field"]}.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选
	        });
	        
	        demoListView_{$info["field"]}.append(tr);
	      });
	    }

在progress回调函数里面根据文件名判断文件上传进度 并 改变进度条的值

    ,progress:function(n, elem, res,filename){
		//循环所有进度条
	   $("#field_parent_td_picture").find('.layui-progress').each(function () {
	   			//如果传来的文件名 == 当前循环的进度条中file属性 就向当前进度条增加进度
            	if($(this).attr("file") == filename.name){
            	var progressBarName = $(this).attr("lay-filter")
                element.progress(progressBarName, n+'%')//设置页面进度
            	}
	         })          
	    }

过程就是这样这里总结两点:

Ajax中接收文件上传进度要注意的是ajax的属性contentType和processData要设置为false

contentTypeString

(默认: "application/x-www-form-urlencoded") 发送信息至服务器时内容编码类型。默认值适合大多数情况。如果你明确地传递了一个content-type给 $.ajax() 那么他必定会发送给服务器(即使没有数据要发送)

processDataBoolean

(默认: true) 默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。

posted @ 2022-07-30 01:07  Dreams_log  阅读(725)  评论(0)    收藏  举报