JavaScript 如何做断点续传
你有没有遇到过这种情况:下载一个几G的大文件,快完成时突然断网,之前的进度全没了,只能从头再来?换做是你,会不会觉得特别糟心?其实在网页上,这个问题早就有了靠谱的解决办法——断点续传。而JavaScript,就是实现这个功能的关键工具。
什么是JavaScript断点续传?
说白了,断点续传就是让你下载文件时,断网后不用重新开始,只需要从断的地方接着下。JavaScript做这件事,核心就是“分块传”:把一个大文件拆成好几个小“碎片”,下载时一个碎片一个碎片传,每传完一个就记好进度。万一断了,下次就从记好的那个碎片开始传,不用重复传已经完成的部分。

举个生活化的例子,你要把一摞100本的书从仓库搬到家里,直接扛整摞会累得慌,而且搬一半突然下雨,之前搬的还得重搬。但如果每次搬10本,搬完10本就记一次“现在搬了10本”,下雨了就从第11本开始搬,是不是轻松多了?JavaScript的断点续传,就是这个道理——把大文件拆成小碎片,传完就记进度,断了接着传。
JavaScript实现断点续传的关键步骤
要靠JavaScript实现断点续传,其实有几个固定的小步骤,每一步都不难理解。
第一步,得先把文件拆成小碎片。用户选好要下载的大文件后,用JavaScript的Blob对象就能把它切成固定大小的块,比如每块1MB。假设文件是10MB,就会分成10个块,编号从0到9。这就像把100本书分成10组,每组10本,给每组编好号。
第二步,记录已经传完的进度。每传完一个块,就把“已经传到第几个块”存在localStorage里——这个东西就是浏览器给你开的“临时小抽屉”,关了网页也不会丢。比如传完第3块,抽屉里就记上“3”,下次打开直接从第4块开始传。
第三步,用“范围请求”只传没完成的部分。这里要用到fetch或者XMLHttpRequest,在请求里加个Range头,告诉服务器“我要从第X块开始传”。比如上次传到第3块,这次就写Range: bytes=3072-(假设每块1MB,3块就是3072KB),服务器就会只返回后面的块,不会重复传已经传好的。
最后一步,把所有传好的块拼起来。等所有块都传完了,用Blob的concat方法把它们按顺序拼回原来的大文件,这样就能正常打开使用了。
实际用的时候要注意的小细节
虽然步骤简单,但有几个小坑得避开。比如,每块的大小不能太小也不能太大:太小了,请求次数太多,反而拖慢速度;太大了,万一中间断网,损失的部分就多了。一般1MB到5MB是比较合适的。
还有,localStorage的容量有限,别把进度存太复杂的东西,就存“已完成的块编号”就行。另外,要是用户清了浏览器的缓存,进度就会丢失,所以最好也把进度存在服务器里,双重保险。
最后想说,断点续传不是什么高大上的技术,本质就是“拆成小块、记好进度、只传需要的”。JavaScript能做的,就是把这些简单的小事串起来,让大文件下载不再让人头疼。下次你再遇到下载断了的情况,说不定背后就是JavaScript在默默帮你接着传呢。