• 下载过程中,获取进度,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的文件流下载及下载进度获取的更多相关文章

  1. Web Api 将DataTable装换成Excel,并通过文件流将其下载

    不废话,直接上代码 前端代码 <input type="button" class="layui-btn" value="Test-GetFil ...

  2. 后台返回excel文件流,js下载

    /** 下载excel */ downloadExcel(data: Blob): void { var blob = new Blob([data], { type: 'application/vn ...

  3. 七、springBoot 简单优雅是实现文件上传和下载

    前言 好久没有更新spring Boot 这个项目了.最近看了一下docker 的知识,后期打算将spring boot 和docker 结合起来.刚好最近有一个上传文件的工作呢,刚好就想起这个脚手架 ...

  4. js上传文件获取文件流

    上传文件获取文件流 <div> 上传文件 : <input type="file" name = "file" id = "file ...

  5. ASP.NET 实现Base64文件流下载PDF

    因为业务需要调用接口获取的是 Base64文件流 需要提供给客户下载PDF文档 源码部分借鉴网上,具体地址忘记了. //Base64文件流 byte[] buffer = Convert.FromBa ...

  6. koa2基于stream(流)进行文件上传和下载

    阅读目录 一:上传文件(包括单个文件或多个文件上传) 二:下载文件 回到顶部 一:上传文件(包括单个文件或多个文件上传) 在之前一篇文章,我们了解到nodejs中的流的概念,也了解到了使用流的优点,具 ...

  7. .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常)

    .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常) 前段时间项目使用一次性读去SQL Server中保存的电子文件的文件流然后返回给客户端保存下载电子文件, ...

  8. asp.net已流的方式下载文件

    string filePath = context.Server.MapPath("~/" + uploadFolder+"/"+file_name);//路径 ...

  9. Android OkHttp文件上传与下载的进度监听扩展

    http://www.loongwind.com/archives/290.html 上一篇文章介绍了用Retrofit实现文件的上传与下载,但是我们发现没办法监听上传下载的进度,毕竟我们在做开发的时 ...

随机推荐

  1. Springboot将mybatis替换为mybatis-plus

    知识点: 1.Mybatis-plus相比mybatis,功能更加强大,简而言之,不需要我们去写mapper.xml配置,但是对于特殊需求的sql语句,还是需要写mapper.xml文件中的sql语句 ...

  2. 一百一十八:CMS系统之短信验证码加密和js代码混淆

    前面的方法存在安全隐患,只要知道发送短信验证码的接口就可以无限触发发送短信验证码 改用post请求,在前端加scrf_token验证,后面需要使用到md5加密,引入md5 from apps.form ...

  3. Win10上的媒体断开连接错误消息(找不到ip地址)

    使用管理员权限打开命令提示符并执行以下命令: ipconfig /all 这将列出所有连接的媒体,即以太网和Wifi及其状态. 结果全部显示: 媒体断开连接 如下图: 如果是这种情况,我们需要解决互联 ...

  4. 一起学习linux环境的git

    第一节 GIT最初是由Linus Benedict Torvalds为了更有效地管理Linux内核开发而创立的分布式版本控制软件,与常用的版本控制工具如CVS.Subversion不同,它不必服务器端 ...

  5. VS2012编译php扩展

    注意:用VS2015来做会比较好! 开发前准备工作:cygwinvisual studio 2012php编译后的程序      使用的是 xampp集成安装包,所以编译后的程序路径为D:\xampp ...

  6. Java内部类(5):应用例

    例1-闭包(Closure) 闭包是一个可调用的对象(通过Callback),它记录了一些信息,这些信息来自于创建它的作用域 interface Incrementable { void increm ...

  7. Python3 Selenium自动化web测试 ==> 第二节 页面元素的定位方法 -- iframe专题 <下>

    学习目的: 掌握iframe矿建的定位,因为前端的iframe框架页面元素信息,大多时候都会带有动态ID,无法重复定位. 场景: 1. iframe切换 查看iframe 切换iframe 多个ifr ...

  8. Netcat—瑞士军刀

    netcat是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据.通过与其他工具结合和重定向,你可以在脚本中以多种方式使用它.使用netcat命令所能完成的事情令人惊讶. netcat所做的 ...

  9. 【并行计算-CUDA开发】GPGPU OpenCL/CUDA 高性能编程的10大注意事项

    GPGPU OpenCL/CUDA 高性能编程的10大注意事项 1.展开循环 如果提前知道了循环的次数,可以进行循环展开,这样省去了循环条件的比较次数.但是同时也不能使得kernel代码太大. 循环展 ...

  10. JavaScript日期格式化处理

    /** * 获取年月,如:2018-08 */ export function getMonth () { return formatDate(new Date(), 'yyyy-MM') } /** ...