如何实现断点续传?

断点续传允许文件在上传过程中因网络中断或用户暂停后,能从上次中断的位置继续上传,而不是重新开始。这对于大文件上传至关重要,能显著提升用户体验和上传成功率。其核心原理是将大文件切割成多个小块,并记录每个块的传输状态。

前端文件分块与状态管理

首先,前端需要将待上传的大文件进行逻辑分块。通常使用Blob.slice()方法来切割文件。

async function createFileChunks(file, chunkSize = 1024 * 1024) { // 默认1MB一块
  const chunks = [];
  let start = 0;
  while (start < file.size) {
    const chunk = file.slice(start, start + chunkSize);
    chunks.push({
      index: chunks.length,
      chunk: chunk,
      start: start
    });
    start += chunkSize;
  }
  return chunks;
}

每个分块需要包含自己的索引、数据以及在整个文件中的起始位置。前端需要维护一个状态,记录哪些分块已上传成功,哪些尚未上传或失败。这个状态可以持久化到localStorage中,以便页面刷新后恢复。

上传分块与记录进度

上传时,遍历所有分块,并只上传那些尚未标记为“已成功”的块。使用FormData携带分块数据、索引和文件唯一标识(如文件哈希)。

async function uploadChunk(chunkData, fileHash) {
  const formData = new FormData();
  formData.append('chunk', chunkData.chunk);
  formData.append('index', chunkData.index);
  formData.append('hash', fileHash);

  await fetch('/api/upload-chunk', {
    method: 'POST',
    body: formData
  });
  // 上传成功后,将当前分块索引标记为已完成,并保存状态
  markChunkAsUploaded(chunkData.index, fileHash);
}

markChunkAsUploaded函数中,将已上传的分块索引记录到localStorage中。在上传开始前,先读取这个记录,跳过已上传的块。

服务端接收与合并分块

服务端需要提供一个接口来接收每个分块。接口根据前端传来的文件唯一标识(hash)和分块索引(index),将分块数据临时存储(例如以{hash}-{index}.chunk的形式保存在服务器临时目录)。

// 服务端(Node.js示例)保存分块
const path = require('path');
const fs = require('fs').promises;
app.post('/api/upload-chunk', async (req, res) => {
  const { index, hash } = req.body;
  const chunk = req.files.chunk;
  const chunkDir = `./temp/${hash}`;
  await fs.mkdir(chunkDir, { recursive: true });
  await fs.rename(chunk.path, path.join(chunkDir, `${index}`));
  res.json({ success: true });
});

当所有分块上传完毕后,前端需要发送一个请求通知服务端进行合并。

async function mergeChunks(fileName, fileHash, totalChunks) {
  await fetch('/api/merge', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ fileName, hash: fileHash, totalChunks })
  });
}

服务端的合并接口,根据hash找到对应的临时目录,按分块索引顺序读取所有分块文件,将它们流式合并成一个完整的文件,并清理临时文件。

因此,断点续传的实现是前后端协作的典型例子。前端负责分片、状态管理和续传触发;后端负责分片存储、校验和最终合并。这为可靠的大文件传输提供了基础,并可在此基础上扩展秒传、并发控制等高级特性。

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容