js⽂件下载,使⽤indexedDB在H5页⾯中完成⼤⽂件的断点分⽚下载能⼒,并完成最终的。。。
产品需求没有做不到,只有想不到。
今天的需求:直接在H5页⾯实现⼤⽂件分⽚下载,合并,另存为⽂件,完成⼤⽂件的断点续传下载功能。
为什么要这么做:特殊的情况下我们不希望暴露⽂件下载地址,且⽂件下载地址需要有登录权限的cookie或者token鉴权后才允许下载,并不希望⽤户拿到下载地址后去别的⼯具上下载,能尽量规避⽂件传播的风险。适⽤的范围可能还会有其他的场景。
⼀直以来,下载⼯作都是交给浏览器直接去下载,或者是下载⼯具如迅雷去做,在H5中通过JS来实现⽂件下载功能没有现成的放案,接下来我会将实现流程,完整的提供给⼤家。
下⾯是简单的demo效果截图
实现流程
⽂件断点下载原理其实是将需要下载的⽂件分成很多分⽚,每个⽂件分⽚1M(不固定,也可以是2M,5M都⾏)。
⼀个1G的⽂件会被分成 1000个分⽚,每次ajax下载⼀个分⽚,并存储在浏览器⾥,然后下载下⼀个分⽚,直到⽂件所有分⽚都下载成功后,将所有的分⽚合并成源⽂件,并提⽰⽤户保存到⽂件,完成下载流程。
1.js 通过ajax 下载分⽚⽂件获得blob是很好实现。
var xhr = new XMLHttpRequest();
xhr.open("GET", downobj.filePartitionUrls[downobj.downSuccessPartitionCount], true);//open false 是同步请求,不会异步触发
xhr.send();
2.下载的blob⽂件需要在本地浏览器中做持久化存储,为什么要在浏览器中持久化存储,因为⼏千个分⽚的⽂件,⽤户可能下载了⼏个分⽚,就把浏览器关掉,去⼲别的事情了,回头再来打开浏览器进⾏下载,这个情况下如果已经下载的分⽚没有持久化存储,就会丢失,⽂件就得从头重新下载了。
那h5中如何实现类容的持久存储呢,我们都知道浏览器有LocalStorage 和sessionStorage,但是很明显sessionStorage是不适合的,因为浏览器关闭会清空会话数据,LocalStorage能够实现持久化存储,不会在⽹页关闭后丢失数据,但是LocalStorage有⼀个限制,同⼀个域名下最⼤存储5M数据(浏览器不同稍有差异)。
显然LocalStorage的存储容量5M完全⽆法满⾜我们的⽂件分⽚存储需求,超过5M的⽂件⽆法被存起来。
有了indexedDb ,我们下载的⽂件分⽚就能全部存在indexedDb中了。
3.当⽂件分⽚都下载完成了,我们就应该从indexedDb 中取出所有的分⽚⽂件,并且将分⽚按照顺序合并成⼀个⽂件包
将所有分⽚⽂件的blob数据合并成⼀个数组。并将数组合并为⼀个Blob数据对象。
伪代码
let pratition1=blobData1;//分⽚1的blob数据
let pratition2=blobData2;//分⽚2的blob数据
...
let allFileData = [pratition1,pratition2,...];//将所有分⽚BLOB数据合并到⼀个数组
var fileBlob = new Blob(allData,{type:"application/octet-stream;charset=utf-8"});//合并后的数组转成⼀个Blob对象。
4.将合并好的⽂件触发本地下载或者说另存为的操作。
var link = ateElement('a')
link.href = ateObjectURL(blobFile);//传⼊所有分⽚合并后⽣成的Blob对象
js合并两个数组link.download = "⽂件名称";//保存出来的⽂件名称
link.click();//触发内存数据存到⽂件的操作
vokeObjectURL(link.href);//释放内存
5.到这⾥就会触发浏览器的⽂件保存操作。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论