返回

如何使用HTML5实现分片上传GB级大文件?

前端

如今,随着互联网的快速发展,人们对大文件传输的需求日益增长。GB级大文件传输的需求也越来越普遍。然而,传统的HTTP上传方式对大文件的传输并不友好,不仅速度慢,而且容易出错。因此,为了解决这一问题,HTML5提出了分片上传方案。分片上传将大文件切割成多个小片段,然后逐个上传到服务器,大大提高了传输速度和稳定性。
前端部分:

  1. 将HTML5的FileReader API读取文件并将其切割成小片段。
  2. 使用XMLHttpRequest对象将每个分片发送到服务器端。
  3. 在服务器端处理每个分片并将其存储到目标位置。
  4. 当所有分片都上传完成后,将它们合并成一个完整的文件。

后端部分:

  1. 使用合适的Web框架或HTTP服务器接收和处理分片请求。
  2. 将每个分片存储到临时目录或数据库中。
  3. 当所有分片都上传完成后,将它们合并成一个完整的文件。
  4. 将合并后的文件发送给客户端或将其存储在服务器上。

示例代码:
前端:

<input type="file" multiple id="file-input" />
<script>
  const fileInput = document.getElementById('file-input');
  const chunkSize = 1024 * 1024; // 1MB

  fileInput.addEventListener('change', () => {
    const files = fileInput.files;
    for (const file of files) {
      const reader = new FileReader();
      reader.onload = () => {
        const arrayBuffer = reader.result;
        const chunks = [];
        for (let i = 0; i < arrayBuffer.byteLength; i += chunkSize) {
          chunks.push(arrayBuffer.slice(i, i + chunkSize));
        }
        // 发送分片到服务器
        sendChunks(chunks, file.name);
      };
      reader.readAsArrayBuffer(file);
    }
  });

  const sendChunks = (chunks, fileName) => {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload');
    xhr.setRequestHeader('Content-Type', 'multipart/form-data');
    xhr.onload = () => {
      // 处理服务器返回的结果
    };
    const formData = new FormData();
    formData.append('fileName', fileName);
    for (let i = 0; i < chunks.length; i++) {
      formData.append('chunk' + i, chunks[i]);
    }
    xhr.send(formData);
  };
</script>

后端:

<?php
// 接收分片请求
if (isset($_FILES['chunk'])) {
  $chunk = $_FILES['chunk'];
  $fileName = $_POST['fileName'];
  // 将分片存储到临时目录
  $tmpDir = 'tmp/';
  move_uploaded_file($chunk['tmp_name'], $tmpDir . $fileName . '_' . $chunk['name']);
} else {
  // 所有分片都上传完成后,合并分片并保存文件
  $fileName = $_POST['fileName'];
  $tmpDir = 'tmp/';
  $chunks = scandir($tmpDir);
  $file = fopen($fileName, 'wb');
  foreach ($chunks as $chunk) {
    if (strpos($chunk, $fileName) !== false) {
      $chunkData = file_get_contents($tmpDir . $chunk);
      fwrite($file, $chunkData);
      unlink($tmpDir . $chunk);
    }
  }
  fclose($file);
}
?>

这种分片上传方案不仅适用于前端,还适用于后端。它不仅可以提高传输速度,还可以降低服务器的负载。并且,HTML5的分片上传方案还具有良好的兼容性,可以支持主流浏览器。