返回

文件切片上传与断点续传,提升文件上传体验

前端

引言

文件上传是Web应用程序中一项常见的操作,例如上传图片、视频、文档等。然而,当上传大文件时,可能会遇到一些问题,例如:

  • 网络不稳定导致上传失败: 在大文件上传过程中,如果网络不稳定,可能会导致上传失败,需要重新上传。
  • 页面刷新导致上传中断: 如果在文件上传过程中刷新页面,也会导致上传中断,需要重新上传。
  • 上传速度慢: 大文件上传可能会花费很长时间,尤其是在网络速度较慢的情况下。

为了解决这些问题,我们可以使用文件切片上传和断点续传技术。

文件切片上传

文件切片上传是指将大文件分成更小的切片,然后分段上传。这样,即使网络不稳定或页面刷新,也不会影响整个文件的上传,只需要重新上传失败的切片即可。

要实现文件切片上传,我们可以使用JavaScript的FileReader对象。FileReader对象可以将文件读取为二进制数据,然后我们可以使用Blob对象将二进制数据分段成更小的切片。

const file = document.getElementById('file-input').files[0];
const reader = new FileReader();

reader.onload = function() {
  const binaryData = reader.result;
  const chunkSize = 1024 * 1024; // 1MB
  const chunks = [];

  for (let i = 0; i < binaryData.length; i += chunkSize) {
    const chunk = binaryData.slice(i, i + chunkSize);
    chunks.push(chunk);
  }

  // 上传分段
  for (const chunk of chunks) {
    // 发送请求上传分段
  }
};

reader.readAsArrayBuffer(file);

断点续传

断点续传是指在文件上传中断后,能够从中断点继续上传,而无需重新上传整个文件。要实现断点续传,我们需要在服务器端记录每个文件的上传进度。当客户端重新上传文件时,可以将文件切片从中断点开始上传。

// 获取文件上传进度
const progress = await fetch('/api/file-progress', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    file_id: file_id,
  }),
});

// 如果文件已经上传完成,则直接返回
if (progress.status === 200) {
  return;
}

// 计算中断点
const startByte = progress.headers.get('Content-Range').split('/')[1];

// 从中断点继续上传
const formData = new FormData();
formData.append('file', file.slice(startByte));

const response = await fetch('/api/file-upload', {
  method: 'POST',
  headers: {
    'Content-Type': 'multipart/form-data',
  },
  body: formData,
});

结论

通过使用文件切片上传和断点续传技术,我们可以大大提升文件上传的体验,避免因网络不稳定或页面刷新而导致的重新上传。这些技术在Web应用程序中非常有用,尤其是需要上传大文件时。