js实现分包传输大文件
使用分块上传技术
在JavaScript中,可以通过Blob.slice()方法将大文件分割成多个小块,然后通过FormData逐个上传。这种方法适合处理大文件上传,避免单次请求超时或内存不足。
const uploadFile = async (file, chunkSize = 5 * 1024 * 1024) => {
const totalChunks = Math.ceil(file.size / chunkSize);
for (let i = 0; i < totalChunks; 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('chunkIndex', i);
formData.append('totalChunks', totalChunks);
formData.append('fileName', file.name);
await fetch('/upload', {
method: 'POST',
body: formData
});
}
};
利用Web Workers处理计算密集型任务
如果文件分块涉及复杂计算(如哈希校验),可以使用Web Workers在后台线程处理,避免阻塞主线程。
// worker.js
self.onmessage = (e) => {
const { chunk, index } = e.data;
// 计算哈希等操作
postMessage({ index, hash: computedHash });
};
// 主线程
const worker = new Worker('worker.js');
worker.postMessage({ chunk: fileChunk, index: chunkIndex });
断点续传实现
通过记录已上传的块索引,可以在网络中断后恢复上传。需要服务端支持记录上传状态。

const resumeUpload = async (file, uploadedChunks) => {
const chunkSize = 5 * 1024 * 1024;
const totalChunks = Math.ceil(file.size / chunkSize);
for (let i = 0; i < totalChunks; i++) {
if (uploadedChunks.includes(i)) continue;
// 上传逻辑...
}
};
使用Streams API处理超大文件
现代浏览器支持Streams API,可以逐块读取文件内容,显著降低内存占用。
const streamUpload = async (file) => {
const stream = file.stream();
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
// 处理每个value块
await processChunk(value);
}
};
服务端配合注意事项
服务端需要实现以下功能:

- 接收分块并临时存储
- 校验每个块的完整性
- 合并所有分块为完整文件
- 提供上传进度查询接口
典型Node.js合并示例:
const mergeChunks = (fileName, totalChunks) => {
const writeStream = fs.createWriteStream(fileName);
for (let i = 0; i < totalChunks; i++) {
const chunk = fs.readFileSync(`${fileName}.part${i}`);
writeStream.write(chunk);
}
writeStream.end();
};
前端进度反馈
通过事件或Promise提供上传进度反馈:
const uploadWithProgress = (file, onProgress) => {
let uploaded = 0;
// 分块上传逻辑...
onProgress(uploaded / file.size * 100);
};






