当前位置:首页 > JavaScript

js实现分段上传

2026-02-02 19:26:42JavaScript

分段上传的实现方法

分段上传(Chunked Upload)是一种将大文件分割成多个小块分别上传的技术,常用于处理大文件上传或网络不稳定的场景。以下是使用JavaScript实现分段上传的几种方法:

使用XMLHttpRequest实现

XMLHttpRequest是传统的AJAX请求方式,可以通过设置请求头和数据分割实现分段上传。

function uploadFileInChunks(file, chunkSize) {
  const totalChunks = Math.ceil(file.size / chunkSize);
  let currentChunk = 0;

  function uploadNextChunk() {
    const start = currentChunk * chunkSize;
    const end = Math.min(start + chunkSize, file.size);
    const chunk = file.slice(start, end);

    const xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload', true);
    xhr.setRequestHeader('Content-Type', 'application/octet-stream');
    xhr.setRequestHeader('X-Chunk-Number', currentChunk);
    xhr.setRequestHeader('X-Total-Chunks', totalChunks);
    xhr.setRequestHeader('X-File-Name', encodeURIComponent(file.name));

    xhr.onload = function() {
      if (xhr.status === 200) {
        currentChunk++;
        if (currentChunk < totalChunks) {
          uploadNextChunk();
        } else {
          console.log('Upload complete');
        }
      }
    };

    xhr.send(chunk);
  }

  uploadNextChunk();
}

使用Fetch API实现

Fetch API提供了更现代的异步请求方式,结合Blob.slice()方法可以实现分段上传。

async function chunkedUpload(file, chunkSize = 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('file', chunk, file.name);
    formData.append('chunkIndex', i);
    formData.append('totalChunks', totalChunks);

    try {
      const response = await fetch('/upload', {
        method: 'POST',
        body: formData
      });

      if (!response.ok) throw new Error('Upload failed');
    } catch (error) {
      console.error('Error uploading chunk:', error);
      break;
    }
  }
}

使用Resumable.js库实现

Resumable.js是一个专门处理分段上传的JavaScript库,提供了更完善的解决方案。

const r = new Resumable({
  target: '/upload',
  chunkSize: 1 * 1024 * 1024,
  simultaneousUploads: 3,
  testChunks: true
});

r.assignBrowse(document.getElementById('browseButton'));
r.assignDrop(document.getElementById('dropTarget'));

r.on('fileAdded', function(file) {
  r.upload();
});

r.on('fileSuccess', function(file) {
  console.log(file.fileName + ' uploaded successfully');
});

r.on('fileError', function(file, message) {
  console.log('Error uploading ' + file.fileName + ': ' + message);
});

服务器端处理要点

分段上传需要服务器端配合处理,通常需要考虑以下方面:

  • 接收并存储每个文件块
  • 验证每个块的完整性
  • 合并所有块重建完整文件
  • 处理上传中断后的恢复
  • 提供上传进度查询接口

进度跟踪实现

可以通过监听xhr.upload.onprogress或使用Resumable.js内置事件跟踪上传进度。

xhr.upload.onprogress = function(e) {
  if (e.lengthComputable) {
    const percentComplete = (e.loaded / e.total) * 100;
    console.log(percentComplete + '% uploaded');
  }
};

错误处理和恢复

实现断点续传需要在客户端和服务器端记录上传状态:

js实现分段上传

  • 客户端保存已上传的块信息
  • 服务器端验证块完整性
  • 上传前检查哪些块已经上传
// 检查服务器上已上传的块
async function checkUploadedChunks(file, totalChunks) {
  const response = await fetch(`/upload-status?name=${encodeURIComponent(file.name)}`);
  const { uploadedChunks } = await response.json();
  return uploadedChunks;
}

性能优化建议

  • 使用Web Workers处理大文件分割
  • 并行上传多个块(注意服务器承受能力)
  • 压缩文件块减少传输量
  • 实现本地存储暂存上传状态

以上方法可以根据具体需求组合使用,实现高效可靠的分段上传功能。

标签: 上传js
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 或直接使用 window.location 实现页面跳转,适用于普通跳转或带参数的 URL。 // 方…

js实现打印

js实现打印

使用window.print()方法实现打印 在JavaScript中,可以通过调用window.print()方法直接触发浏览器的打印功能。这会打开系统的打印对话框,用户可以选择打印机和设置打印选项…

js实现文件下载

js实现文件下载

使用 a 标签下载文件 通过动态创建 a 标签并设置 download 属性实现文件下载。适用于已知文件 URL 或 Blob 数据的情况。 function downloadFile(url, f…

js实现抽奖

js实现抽奖

实现抽奖功能的基本思路 抽奖功能的核心是随机选择奖项并展示结果。可以通过数组存储奖项,利用随机数生成索引,最后通过动画增强用户体验。 准备奖项数据 定义一个数组存储奖项信息,每个奖项可以包含名称、图…

使用js实现

使用js实现

使用JavaScript实现 JavaScript可以通过Math.random()函数生成随机数,结合其他方法可以实现多种随机数生成需求。 // 生成0到1之间的随机小数 const random…

js实现 功能

js实现 功能

在 JavaScript 中实现功能通常涉及多个关键步骤,具体取决于功能需求。以下是常见功能的实现方法和示例: 基本功能实现 使用函数封装逻辑是最直接的方式。例如,实现一个计算两数之和的函数: f…