id=method=enctype=> name==multiple /> 4 <br /> id==>ajax上传进度效果上传</button> 6 <br /> id=></span> 8 </form>
要加一个进度效果,需要用到js的定时器,定时获取上传文件的上传进度数据信息,因此这里通过js的setInterval方法来定时请求一个进度数据接口,注意用完之后需要清除这个定时器,不然一直再不断请求您接口:
).on(, function () { interBar; ); ); ); data = new FormData(form); 9 10 $.ajax({ , , 13 data: data, 14 15 contentType: false, 16 processData: false, 17 success: function (data) { 18 if (data) { 19 msg.html(data.msg); (interBar) { clearInterval(interBar); } 22 } 23 }, 24 error: function () { ); 26 if (interBar) { clearInterval(interBar); } 27 } 28 }); interBar = setInterval(function () { , function (data) { (data) { 36 var isClearVal = true; 37 var strArr = []; 38 $.each(data, function (i, item) { + item.fileName + + item.percentBar + ); 40 if (item.status != 2) { isClearVal = false; } 41 }); 42 msg.html(strArr.join('')); 43 if (isClearVal) { 44 if (interBar) { clearInterval(interBar); } 45 } 46 } 47 }); 48 }, 200); 49 });
既然上面说到单独的进度数据接口,那么我们除了上传Action外,也需要进度的Action,而这进度Action得到的上传文件数据信息必须和上传的Action一直,因此就需要用到缓存等存储数据的方式,这里我用的是MemoryCache的方式,对已netcore来说仅仅只需要在起始文件(如:Startup.cs)中添加组件服务:
ConfigureServices(IServiceCollection services) 2 { services.AddMvc(); services.AddDistributedMemoryCache(); 8 }
然后通过构造函数注入到对应的接口Controller中去:
1 readonly IMemoryCache _cache; HomeController(IOptions<MoOptions> options, ILogger<HomeController> logger, IMemoryCache cache) 4 { 5 this._options = options.Value; 6 _logger = logger; 7 _cache = cache; 8 }
到此我们就能利用cache来存储我们上传进度信息了,来看下处理上传的Action:
cacheKey = ; cacheKey03 = ; ajax上传进度效果上传 [HttpPost] Task<JsonResult> AjaxFileUp02() 9 { }; { ); (files == ; return Json(data); } allowType = , }; 19 if (files.Any(b => !allowType.Contains(b.ContentType))) 20 { ,; 22 return Json(data); 23 } (files.Sum(b => b.Length) >= 1024 * 1024 * 4) 27 { ; return Json(data); 29 } listBar = new List<MoBar>(); 33 files.ToList().ForEach(b => 34 { 35 listBar.Add(new MoBar 36 { 37 FileName = b.FileName, 38 Status = 1, 39 CurrBar = 0, 40 TotalBar = b.Length 41 }); 42 }); 43 _cache.Set<List<MoBar>>(cacheKey, listBar); (var file in files) 47 { totalSize = file.Length; readSize = 1024L; [totalSize > readSize ? readSize : totalSize]; currentSize = 0L; fileName = file.FileName; , fileName); 58 using (var stream = System.IO.File.Create(path)) 59 { 60 //await file.CopyToAsync(stream); (var inputStream = file.OpenReadStream()) 63 { (await inputStream.ReadAsync(bt, 0, bt.Length) > 0) 66 { currentSize += bt.Length; stream.WriteAsync(bt, 0, bt.Length); readSize = currentSize + readSize <= totalSize ? 76 readSize : 77 totalSize - currentSize; bt = new byte[readSize]; bars = _cache.Get<List<MoBar>>(cacheKey); 83 var currBar = bars.Where(b => b.FileName == fileName).SingleOrDefault(); 84 currBar.CurrBar = currentSize; 85 currBar.Status = currentSize >= totalSize ? 2 : 1; 86 _cache.Set<List<MoBar>>(cacheKey, bars); 87 88 System.Threading.Thread.Sleep(1000 * 1); 89 } 90 } 91 } 92 } ; 94 data.Status = 2; 95 } 96 catch (Exception ex) 97 { 98 data.Msg = ex.Message; 99 } 100 return Json(data); 101 }
代码一下子就变多了,其实按照逻辑来说增加了存储进度的Cache,和逐一读取上传文件流的逻辑而已,具体大家可以仔细看下代码,都有备注说明;再来就是咋们的进度信息Action接口: