fetch的文件流下载及下载进度获取
- 下载过程中,获取进度,fetch API并没有提供类似xhr和ajax的 progress所以用 getReader()来循环读取大小
let size = 0;
fetch( URL() + `/sys/file/download/${uuid}`,{
method: 'GET',
headers:{
token,
}
})
.then(response => {
if(response.ok){
return response;
}else{
console.log("请求失败")
}
})
// 取出body
.then(response => response.body)
.then(body => {
const reader = body.getReader();
return new ReadableStream({
start(controller) {
return pump();
function pump() {
return reader.read().then(res => { //res ({ done, value })
// 读不到更多数据就关闭流
console.log(res,"res");
const {done,value } = res;
if (done) {
console.log("end")
controller.close();
// return;
}
size += value.length || 0;
console.log(size,"size")
// 将下一个数据块置入流中
controller.enqueue(value);
return pump();
});
}
}
})
})
.then(stream => new Response(stream))
.then(response => that.savingFile(response,fileName))
.catch(err => console.error(err));
- 上一步中接收到文件流后,通过Blob和a标签进行下载
savingFile = (response,fileName) => {
const that = this;
response.blob().then( blob => {
if(typeof FileReader === 'undefined'){
notification.open({
message:'您的浏览器不支持 FileReader,请升级浏览器',
icon: <Icon type="smile" style={{ color: '#108ee9' }} />
})
}
const reader = new FileReader();
reader.addEventListener("loadend", function() {
let resu = '';
try{
resu = JSON.parse( reader.result);
// resu = eval('('+ reader.result + ')')
if(resu.code == 500){
notification.open({
message:resu.msg,
icon: <Icon type="smile" style={{ color: '#108ee9' }} />
})
}else if(resu.code == 401){
notification.error({
message:resu.msg
})
}
}catch(e){
//捕获错误 说明是文本字符串
resu = reader.result;
downloadBlob(blob,fileName);
}
});
reader.readAsText(blob);
//下载
function downloadBlob(blob,fileName){
let blobUrl = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = blobUrl;
a.target = '_blank';
a.style.display = 'none'
document.body.appendChild(a)
a.download = fileName;
a.click();
window.URL.revokeObjectURL(blobUrl);
document.body.removeChild(a)
that.setState({
downloading:false
})
}
})
}
总结一下: 这种前端下载的方式,感觉体验还不是很好。主要考虑是文件流的下载方式,是先下载完全部数据才弹出保存窗口,而大部分软件下载的网站是用a标签直接下载的。这样是先弹出窗口,再利用浏览器的下载工具进行下载,虽然少了一些定制显示,但用户体验上应该会好一点。 再找个下载文件的网站参考参考。
fetch的文件流下载及下载进度获取的更多相关文章
- Web Api 将DataTable装换成Excel,并通过文件流将其下载
不废话,直接上代码 前端代码 <input type="button" class="layui-btn" value="Test-GetFil ...
- 后台返回excel文件流,js下载
/** 下载excel */ downloadExcel(data: Blob): void { var blob = new Blob([data], { type: 'application/vn ...
- 七、springBoot 简单优雅是实现文件上传和下载
前言 好久没有更新spring Boot 这个项目了.最近看了一下docker 的知识,后期打算将spring boot 和docker 结合起来.刚好最近有一个上传文件的工作呢,刚好就想起这个脚手架 ...
- js上传文件获取文件流
上传文件获取文件流 <div> 上传文件 : <input type="file" name = "file" id = "file ...
- ASP.NET 实现Base64文件流下载PDF
因为业务需要调用接口获取的是 Base64文件流 需要提供给客户下载PDF文档 源码部分借鉴网上,具体地址忘记了. //Base64文件流 byte[] buffer = Convert.FromBa ...
- koa2基于stream(流)进行文件上传和下载
阅读目录 一:上传文件(包括单个文件或多个文件上传) 二:下载文件 回到顶部 一:上传文件(包括单个文件或多个文件上传) 在之前一篇文章,我们了解到nodejs中的流的概念,也了解到了使用流的优点,具 ...
- .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常)
.NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常) 前段时间项目使用一次性读去SQL Server中保存的电子文件的文件流然后返回给客户端保存下载电子文件, ...
- asp.net已流的方式下载文件
string filePath = context.Server.MapPath("~/" + uploadFolder+"/"+file_name);//路径 ...
- Android OkHttp文件上传与下载的进度监听扩展
http://www.loongwind.com/archives/290.html 上一篇文章介绍了用Retrofit实现文件的上传与下载,但是我们发现没办法监听上传下载的进度,毕竟我们在做开发的时 ...
随机推荐
- JavaScript之屏幕上下左右滑动监听
前言 存在这么一个需求,根据用户在屏幕不同的滑动方向(上.下.左.右),使用js脚本判断出不同的滑动行为,更新网页为不同的界面. 源码 参考了博文[1]的源码,但由于存在一些漏洞,比如:上下滑动事件监 ...
- discriminator 鉴别器
在特定的情况下使用不同的pojo进行关联, 鉴别器元素就是被设计来处理这个情况的.鉴别器非常容易理解,因为它的表现很像 Java 语言中的 switch 语句:discriminator 标签常用的两 ...
- Leetcode之动态规划(DP)专题-746. 使用最小花费爬楼梯(Min Cost Climbing Stairs)
Leetcode之动态规划(DP)专题-746. 使用最小花费爬楼梯(Min Cost Climbing Stairs) 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 cost ...
- char、varchar、nchar、nvarchar四种类型
char,nchar是定长,如果没达到指定的长度时将自动以英文空格在其后面填充.优势在于速度较高.varchar,nvarchar属于变长,如果没有达到指定的长度时,不会将自动以英文空格在其后面填充. ...
- fping 命令
NAME fping - send ICMP ECHO_REQUEST packets to network hosts SYNOPSIS fping [ options ] [ systems... ...
- 23.安装php和echarts进行结合展示图表
数据展示 http://echarts.baidu.com/index.html 是一个图像展示 可以到官方实例中选择各种图 通过下载例子 新建echartdome.php <!DOCTYPE ...
- oracle——学习之路(SQL基础)
使用create语句创建表 create table 表名 ( 列名 类型 [null | not null], 列名 类型 [null | not null] ) 在 ...
- Centos修改时间
1. 普通用户 a. 获取超级用户root权限 命令:su或者su -或者su - root b. passwd 用户名 2. 超级用户 a. 打开system-auth文件 命令:vi /etc/p ...
- 虚拟机(Vmware)安装ubuntu18.04和配置调整(三)
三.ubuntu安装软件 1.安装常用软件 python程序员: $ sudo apt install ipython $ sudo apt install ipython3 $ sudo a ...
- array_merge与数组加
array_merge() 索引数组:值不会覆盖,会重新索引; 关联数组:相同的键名,则最后的元素会覆盖其他元素. 数组+ 以左为主,按键加; Array ( [0] => A006 ) + A ...