.Net Core WebAPI + Axios +Vue 实现下载与下载进度条

635 篇文章 16 订阅
236 篇文章 4 订阅

写在前面

老板说:系统很慢,下载半个小时无法下载,是否考虑先压缩再给用户下载?

本来是已经压缩过了,不过第一反应应该是用户下的数量多,导致压缩包很大,然后自己测试发现,只是等待的时间比较久而已,仍然是下载状态中,并不是系统慢,但是用户体验肯定是最直观的,确实是我们做得不够好,单纯弹出遮罩层显示冰冷的“拼命加载中……”,对用户来说确实不够友好。嗯,了解实际情况了,那就开撸,增加用户体验。

 解决它

效果图:

Vue+ElementUI

  •  

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();     
        document.body.removeChild(link); 
        this.$message.success('下载成功');
      })
      .catch(() => {
        this.fullscreenLoading = false;
      });
    },

下载:

分片下载:


public static class HttpContextExtension
    {
        /// <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;
                    }
                }
            }
        }
    }

完美~

Vue 3.0 和 ASP.NET Core WebAPI 都支持动态路由,实现起来也比较简单。 首先,在 ASP.NET Core WebAPI 中,我们需要在 Startup.cs 中配置路由。可以使用以下代码: ``` app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller}/{action}/{id?}"); }); ``` 这个配置会将请求转发到对应的控制器和方法中。其中,{controller} 和 {action} 表示控制器和方法名,{id?} 表示可选参数。 接着,在 Vue 3.0 中,我们可以使用 vue-router 实现动态路由。可以使用以下代码: ``` const router = createRouter({ history: createWebHistory(), routes: [ { path: '/:controller/:action/:id?', name: 'dynamic', component: DynamicComponent } ] }) ``` 这个配置会将请求转发到 DynamicComponent 组件中。其中,:controller、:action 和 :id? 表示控制器、方法名和可选参数。 最后,我们可以在 DynamicComponent 组件中调用 ASP.NET Core WebAPI 中的动态路由。可以使用以下代码: ``` axios.get(`/api/${this.$route.params.controller}/${this.$route.params.action}/${this.$route.params.id}`) .then(response => { // 处理响应 }) .catch(error => { // 处理错误 }) ``` 这个代码会发送请求到对应的控制器和方法中,其中,this.$route.params.controller、this.$route.params.action 和 this.$route.params.id 分别对应控制器、方法名和参数。 以上就是 Vue 3.0 和 ASP.NET Core WebAPI 实现动态路由的基本步骤。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值