故事的開始 老闆說:系統很慢,下載半個小時無法下載,是否考慮先壓縮再給用戶下載? 本來是已經壓縮過了,不過第一反應應該是用戶下的數量多,導致壓縮包很大,然後自己測試發現,只是等待的時間比較久而已,仍然是下載狀態中,並不是系統慢,但是用戶體驗肯定是最直觀的,確實是我們做得不夠好,單純彈出遮罩層顯示冰冷 ...
故事的開始
老闆說:系統很慢,下載半個小時無法下載,是否考慮先壓縮再給用戶下載?
本來是已經壓縮過了,不過第一反應應該是用戶下的數量多,導致壓縮包很大,然後自己測試發現,只是等待的時間比較久而已,仍然是下載狀態中,並不是系統慢,但是用戶體驗肯定是最直觀的,確實是我們做得不夠好,單純彈出遮罩層顯示冰冷的“拼命載入中……”,對用戶來說確實不夠友好。嗯,瞭解實際情況了,那就開擼,增加用戶體驗。
解決它
效果圖:
Vue+ElementUI
<el-progress v-if="dlProgress>0" :text-inside="true" :stroke-width="18" :percentage="dlProgress" status="success" style="margin-bottom:10px"></el-progress>
Axios
downloadTask(index,row) { let own =this; this.fullscreenLoading = true; this.axios({ method: 'post', url: this.baseUrl + '/api/Task/DownLoad', data: {id: row.id}, responseType: 'blob',
//敲黑板 onDownloadProgress (progress) { own.dlProgress=Math.round(progress.loaded / progress.total * 100); } }) .then((res) => { this.fullscreenLoading = false; let fileName = decodeURI(res.headers["content-disposition"].split("=")[1]); let url = window.URL.createObjectURL(new Blob([res.data])); let link = document.createElement('a'); link.style.display = 'none'; link.href = url; link.setAttribute('download', fileName); document.body.appendChild(link) link.click() this.$message.success('下載成功'); }) .catch(() => { this.fullscreenLoading = false; }); },
下載:
public static class HttpContextExtension { /// <summary> /// 獲取客戶Ip /// </summary> /// <param name="context"></param> /// <returns></returns> public static string GetClientUserIp(this HttpContext context) { var ip = ""; if (context.Request.Headers.ContainsKey("X-Forwarded-For")) { ip = context.Request.Headers["X-Forwarded-For"].ToString(); } if (string.IsNullOrEmpty(ip) && context.Request.Headers.ContainsKey("X-Real-IP")) { ip = context.Request.Headers["X-Real-IP"].ToString(); } if (string.IsNullOrEmpty(ip)) { ip = context.Connection.RemoteIpAddress.MapToIPv4().ToString(); } if (string.IsNullOrEmpty(ip)) return ip; var sp = ip.RemoveSpacing().Split(','); return sp[0]; } /// <summary> /// 通過文件流下載文件 /// </summary> /// <param name="context"></param> /// <param name="filePath">文件完整路徑</param> /// <param name="contentType">訪問這裡 https://tool.oschina.net/commons </param> public static void DownLoadFile(this HttpContext context,string filePath, string contentType= "application/octet-stream") { var fileName = Path.GetFileName(filePath); int bufferSize = 1024; context.Response.ContentType = contentType; context.Response.Headers.Append("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName)); context.Response.Headers.Append("Charset", "utf-8"); context.Response.Headers.Append("Access-Control-Expose-Headers", "Content-Disposition"); //context.Response.Headers.Append("Access-Control-Allow-Origin", "*"); //使用FileStream開始迴圈讀取要下載文件的內容 using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { using (context.Response.Body) { long contentLength = fs.Length; context.Response.ContentLength = contentLength; byte[] buffer; long hasRead = 0; while (hasRead < contentLength) { if (context.RequestAborted.IsCancellationRequested) { break; } buffer = new byte[bufferSize]; //從下載文件中讀取bufferSize(1024位元組)大小的內容到伺服器記憶體中 int currentRead = fs.Read(buffer, 0, bufferSize); context.Response.Body.Write(buffer, 0, currentRead); context.Response.Body.Flush(); hasRead += currentRead; } context.Response.Body.Close(); } fs.Close(); } } /// <summary> /// 通過文件流下載文件 /// </summary> /// <param name="context"></param> /// <param name="filePath">文件完整路徑</param> /// <param name="contentType">訪問這裡 https://tool.oschina.net/commons </param> public static void DownLoadFile(this HttpContext context,string fileName, byte[] fileByte, string contentType = "application/octet-stream") { int bufferSize = 1024; context.Response.ContentType = contentType; context.Response.Headers.Append("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName)); context.Response.Headers.Append("Charset", "utf-8"); context.Response.Headers.Append("Access-Control-Expose-Headers", "Content-Disposition"); //context.Response.Headers.Append("Access-Control-Allow-Origin", "*"); //使用FileStream開始迴圈讀取要下載文件的內容 using (Stream fs = new MemoryStream(fileByte)) { using (context.Response.Body) { long contentLength = fs.Length; context.Response.ContentLength = contentLength; byte[] buffer; long hasRead = 0; while (hasRead < contentLength) { if (context.RequestAborted.IsCancellationRequested) { break; } buffer = new byte[bufferSize]; //從下載文件中讀取bufferSize(1024位元組)大小的內容到伺服器記憶體中 int currentRead = fs.Read(buffer, 0, bufferSize); context.Response.Body.Write(buffer, 0, currentRead); context.Response.Body.Flush(); hasRead += currentRead; } } } } }View Code
完美~