如何用 Blob 与 File 对象在前端实现纯 JS 的文件分片切割

夜雪小哥_3021

夜雪小哥_3021

2026-04-07

430人浏览

原创

blob.slice() 和 file.slice() 行为一致,返回惰性 blob 切片,零拷贝、不触发读取;分片后需手动包装为 file 以保留元信息,合并时会全量加载内存,故仅用于校验。

如何用 blob 与 file 对象在前端实现纯 js 的文件分片切割

什么是 Blob.slice() 和 File.slice() 的实际行为

两者本质相同:File 继承自 Blob,slice() 方法在两个类型上行为一致,返回新的 Blob 对象,不触发读取或解码,纯内存引用切割(底层是字节范围映射),零拷贝、低开销。

关键点:slice() 不修改原对象,也不加载内容到 JS 内存;切片结果仍是惰性对象,直到你用 FileReader、URL.createObjectURL() 或 arrayBuffer() 等方法真正读取时才触发数据提取。

常见误判:以为 slice() 会立刻生成新二进制数据——其实不会。这也是它适合大文件分片的根本原因。

如何安全地分片并避免越界和类型丢失

分片逻辑本身简单,但容易在边界和类型处理上出错。尤其当原始对象是 File 时,切片后得到的是 Blob,丢失 name、lastModified 等元信息,上传时可能影响后端识别。

  • 始终用 Math.min() 控制末尾片大小,防止 start + chunkSize > blob.size 导致空 Blob(Chrome 返回空,Firefox 可能抛错)
  • 手动补全元信息:对每个切片 Blob,可用 new File([blob], originalFile.name, { type: originalFile.type }) 包一层,恢复为 File 实例(注意:这不会复制数据,只是包装)
  • 起始偏移量必须是整数,且推荐用 start = i * chunkSize 而非累积加法,避免浮点误差导致错位
  • slice() 的第三个参数 contentType 很少需要传——它只设置新 Blob 的 type,不影响内容解析;若需保持原类型,显式传 blob.type

分片后怎么拼回去?前端能否无损还原原始 File?

不能直接“拼回”成同一个 File 对象,但可以合成内容等价的 File 或 Blob。重点不是还原对象身份,而是保证二进制一致性。

Wjs Localizing Video
Wjs Localizing Video

用于端到端视频本地化流程的轻量编排器,路由至四个专注子技能——/wjs-transcribing-audio、/wjs-translating-subtitles...

下载

实操路径:

  • 用 Promise.all(chunks.map(blob => blob.arrayBuffer())) 并行读取所有分片的 ArrayBuffer
  • 合并 ArrayBuffer:用 Uint8Array 分配总长度缓冲区,逐个 set() 写入
  • 用 new Blob([mergedUint8Array.buffer], { type: original.type }) 构造新 Blob
  • 如需 File,再包一层:new File([blob], original.name, { lastModified: original.lastModified })

注意:合并过程会将全部数据载入内存,1GB 文件分 100 片,合并时至少占用 1GB RAM —— 这正是分片的意义所在:避免单次全量加载。所以“拼回去”仅用于校验或调试,生产中应由服务端完成合并。

为什么 FileReader.readAsArrayBuffer() 比 readAsDataURL() 更适合分片上传

readAsDataURL() 会把二进制转 Base64,体积膨胀约 33%,且编码过程阻塞主线程、无法中断;而分片场景下每片都要走一遍,性能和内存代价都不可接受。

readAsArrayBuffer() 直接暴露原始字节,无转换开销,配合 progress 事件还能精确上报每片上传进度。

  • 务必监听 onload 而非 onloadend 获取结果:event.target.result 是 ArrayBuffer,可直接用于 fetch 的 body
  • 不要在 onload 外访问 result——它是异步写入的,未完成时为 null
  • 如果用 fetch 上传,直接传 blob.slice(start, end) 即可,无需先读成 ArrayBuffer;只有需要校验、加密或加签时才主动读取

真正容易被忽略的是:分片上传的可靠性不取决于前端切多细,而在于断点续传状态管理与服务端分片索引对齐。前端只管按约定生成正确字节范围的 Blob,其余交给协议设计。

前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2383

5

前端如何实现即时通讯
前端如何实现即时通讯

实现即时通讯的方法有WebSocket、Long Polling、Server-Sent Events、WebRTC等等。详细介绍:1、WebSocket,它可以在客户端和服务器之间建立持久连接,实现实时的双向通信,前端可以使用 WebSocket API来创建WebSocket连接,并通过发送和接收消息来实现即时通讯;2、Long Polling,是一种模拟实时通信的技术等等。

2023.10.09

5123

6

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

6190

13

php和前端的关联介绍
php和前端的关联介绍

php既可以作为前端语言,也可以作为后端语言。想了解更多php和前端的相关内容,可以阅读本专题下面的文章。

2024.03.22

5738

10

前端外包工作内容有哪些
前端外包工作内容有哪些

前端外包工作内容包括:1. 网站和应用程序开发;2. 用户界面和交互设计;3. 用户体验优化;4. 设计和视觉开发;5. 跨浏览器兼容性;6. 性能优化;7. 维护和更新;8. 项目管理和沟通。想了解更多前端的相关内容,可以阅读本专题下面的文章。

2024.05.22

823

5

js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

4706

5

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

2023.07.04

1169

3

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

2023.07.04

4644

6

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

920

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 20.9万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.8万人学习