前言
随着项目的深入,以前对于后端返回的文件流,前端等待几十秒就可以下载成功,但是现在一个文件最少也有1GB 的文件,等待时间太久,不确定到底有没有还在继续下载,所以前端要获取浏览器中的下载进度并展示在页面上,告知用户还在继续下载,请耐心等待。。。
主要使用的是onDownloadProgress这个方法,axios中增加onDownloadProgress进度条的处理,该方法的主要返回的参数有,见下图
loaded:当前下载的大小,单位为byte(字节)
total:下载文件的公共的大小,total等于0有俩种情况,total的值为content-length的值,
1)后端没有返回这个值得大小,需请后端大哥加上`HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestProperty("Content-Length", 1024);`(1024 为获取到的文件的大小)
2)开启了gzip。开启gzip之后服务器默认就会开启文件分块编码【Transfer-Encoding: chunked】,分块编码把「报文」分割成若干个大小已知的块,块之间是紧挨着发送的。采用这种传输方式进行响应时,没必要带上Content-Length这个首部信息。因为即使带上了也是不准确的,所以content-length会没有。
api接口的写法
export function findAsyncFile(params,downloadProgress) {
// downloadProgress,将处理的progress作为参数回调自己的方法
return request({
url:`/qjt/async/findAsyncFile?fileName=${params.fileName}&id=${params.id}`,
method: 'post',
responseType: 'blob',//将文件流转成blob对象
noErrorMsg: true,
onDownloadProgress: function (progressEvent) {
console.log(progressEvent);
downloadProgress(progressEvent)
},
})
}
代码请求的写法
// 获取当前下载进度
showProgess(progress){
// console.log("prosss",progress);
// 当前浏览器下载的单位为byte,需要转换成MB
this.currentPercent = progress.loaded / 1024 / 1024
// 如果progress.total的值不等于0,也可以使用progress.loaded / progress.total
},
//通用下载
generalDown(id, fileName) {
let parmas = {
id: id,
fileName: fileName,
};
let that = this
//that.showProgess 作为接口参数的downloadProgress
findAsyncFile(parmas,that.showProgess).then((res) => {
//导出异常
let read = new FileReader();
read.readAsText(res, "utf-8");
let that = this;
let bugMsg = "";
read.onload = (data) => {
bugMsg = JSON.parse(data.currentTarget.result).msg;
that.$message.error(JSON.parse(data.currentTarget.result).msg);
if (!bugMsg) {
bugMsg = "未知异常";
}
});
}
}
currentPercent的值 就是当前浏览器中下载的值.
最后
以此来自己记录这个知识点,也希望可以帮助更多的人。。。
如果对您有用,希望您留下评论/👍/收藏。
您的三连,是对我创作的最大的鼓励🙇♀️🙇♀️🙇♀️