上一篇
html5分片上传api
- 行业动态
- 2025-05-04
- 3197
HTML5分片上传API通过File对象切片,结合XHR逐块传输,支持断点续
核心概念
HTML5分片上传(Chunked/Sliced File Upload)是一种将大文件分割为多个小片段(分片)后逐片上传的技术,通过Blob.slice()
方法切割文件,结合XMLHttpRequest
或Fetch
实现分片传输,适用于大文件上传、断点续传等场景。
实现步骤
文件切片
使用Blob.slice()
方法将文件分割为多个分片,每个分片为Blob
对象。const file = document.querySelector('input[type="file"]').files[0]; const chunkSize = 1 1024 1024; // 1MB const chunks = Math.ceil(file.size / chunkSize); const promises = [];
逐片上传
通过循环遍历分片,使用FormData
或XHR
发送每个分片,携带分片索引、文件ID等元信息。for (let i = 0; i < chunks; i++) { const start = i chunkSize; const end = Math.min(start + chunkSize, file.size); const chunk = file.slice(start, end); const formData = new FormData(); formData.append('file', chunk); formData.append('index', i); formData.append('fileId', file.name); const xhr = new XMLHttpRequest(); xhr.open('POST', '/upload'); xhr.send(formData); promises.push(new Promise((resolve) => { xhr.onload = () => resolve(xhr.response); })); }
合并分片(后端逻辑)
服务器接收所有分片后,按索引顺序合并为完整文件,需记录已上传分片状态以支持断点续传。
技术对比表
特性 | 传统上传 | 分片上传 |
---|---|---|
文件大小限制 | 受单次请求限制 | 无上限(依赖后端存储) |
网络中断影响 | 需重新上传全部 | 可续传未完成分片 |
内存占用 | 高(整个文件加载到内存) | 低(按需加载分片) |
上传进度控制 | 粗略 | 精确到分片级别 |
关键API详解
API | 说明 |
---|---|
Blob.slice() | 提取Blob 对象的指定范围(如file.slice(0, 1024) ) |
FileReader | 读取文件内容(可选用于生成分片哈希值) |
XMLHttpRequest | 发送分片请求,推荐使用xhr.upload.onprogress 监控进度 |
FormData | 构造包含分片和元数据的表单数据 |
常见问题与解决方案
分片大小如何选择?
- 建议根据网络环境和文件类型调整,通常为
1MB-5MB
,过小会增加请求次数,过大可能导致单片上传失败。
- 建议根据网络环境和文件类型调整,通常为
如何实现断点续传?
- 客户端需记录已上传分片的索引(如
localStorage
),重新上传时跳过已完成分片。 - 后端需保存上传状态(如Redis缓存分片信息),合并前校验分片完整性。
- 客户端需记录已上传分片的索引(如
代码示例(前端)
<input type="file" id="fileInput" /> <button onclick="upload()">上传</button> <script> function upload() { const file = document.getElementById('fileInput').files[0]; const chunkSize = 2 1024 1024; // 2MB const chunks = Math.ceil(file.size / chunkSize); for (let i = 0; i < chunks; i++) { const start = i chunkSize; const end = Math.min(start + chunkSize, file.size); const chunk = file.slice(start, end); const formData = new FormData(); formData.append('chunk', chunk); formData.append('index', i); formData.append('fileName', file.name); fetch('/upload', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => console.log(`Chunk ${i} uploaded`)) .catch(err => console.error(`Chunk ${i} failed: ${err}`)); } } </script>
相关问题与解答
问题1:分片上传如何保证文件完整性?
解答:
- 客户端可对每个分片计算哈希值(如MD5),上传时携带哈希参数,后端校验分片完整性。
- 所有分片上传完成后,计算合并后文件的哈希值,与客户端预生成的哈希比对。
问题2:分片上传失败如何处理?
解答:
- 对每个分片设置重试机制(如
3-5
次),失败后标记该分片并提示用户。 - 若为网络波动导致的偶发失败,可自动加入重试队列;若为服务器错误,需