当前位置:首页 > JavaScript

js实现分段上传

2026-04-07 13:11:11JavaScript

分段上传的实现方法

在JavaScript中实现分段上传通常涉及将大文件分割成小块,逐块上传并在服务器端合并。以下是常见的实现方式:

使用XMLHttpRequest或Fetch API

通过前端JavaScript将文件切片,使用AJAX技术逐块上传:

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

  function uploadChunk() {
    const start = chunkNumber * 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('chunkNumber', chunkNumber);
    formData.append('totalChunks', totalChunks);
    formData.append('fileId', file.name + '-' + file.size);

    fetch('/upload', {
      method: 'POST',
      body: formData
    })
    .then(response => {
      chunkNumber++;
      if (chunkNumber < totalChunks) {
        uploadChunk();
      } else {
        console.log('Upload complete');
      }
    });
  }

  uploadChunk();
}

使用Resumable.js等库

Resumable.js是专门处理大文件分段上传的JavaScript库:

js实现分段上传

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');
});

服务器端处理

服务器端需要实现以下功能:

  • 接收分块并临时存储
  • 验证分块完整性
  • 合并所有分块为完整文件
  • 处理上传中断后的恢复

Node.js示例(Express框架):

js实现分段上传

app.post('/upload', (req, res) => {
  const chunk = req.files.chunk;
  const chunkNumber = req.body.chunkNumber;
  const totalChunks = req.body.totalChunks;
  const fileId = req.body.fileId;

  const tempDir = `./temp/${fileId}`;
  if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir);

  chunk.mv(`${tempDir}/${chunkNumber}`, (err) => {
    if (err) return res.status(500).send(err);

    if (parseInt(chunkNumber) === parseInt(totalChunks) - 1) {
      mergeChunks(fileId, totalChunks);
    }

    res.status(200).send('Chunk uploaded');
  });
});

function mergeChunks(fileId, totalChunks) {
  const tempDir = `./temp/${fileId}`;
  const writeStream = fs.createWriteStream(`./uploads/${fileId}`);

  for (let i = 0; i < totalChunks; i++) {
    const chunk = fs.readFileSync(`${tempDir}/${i}`);
    writeStream.write(chunk);
  }

  writeStream.end();
  fs.rmdirSync(tempDir, { recursive: true });
}

进度监控

实现上传进度监控:

const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (event) => {
  if (event.lengthComputable) {
    const percentComplete = (event.loaded / event.total) * 100;
    console.log(percentComplete + '% uploaded');
  }
}, false);

断点续传

实现断点续传需要:

  • 前端记录已上传的分块
  • 服务器端提供已接收分块信息接口
  • 上传前检查哪些分块需要上传
function checkUploadStatus(fileId, totalChunks) {
  return fetch(`/upload-status?fileId=${fileId}`)
    .then(res => res.json())
    .then(data => {
      const uploadedChunks = data.chunks || [];
      return Array.from({length: totalChunks}, (_, i) => i)
        .filter(i => !uploadedChunks.includes(i));
    });
}

注意事项

  • 分块大小需要合理设置,通常1MB-5MB
  • 需要处理网络错误和重试机制
  • 服务器端需要定期清理未完成的临时文件
  • 考虑文件唯一性校验(如MD5)
  • 跨域上传需要配置CORS

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

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

相关文章

js实现复制到剪贴板

js实现复制到剪贴板

使用document.execCommand方法(传统方式,已废弃但部分浏览器仍支持) 该方法适用于旧版浏览器,但已被标记为废弃。执行前需确保文本已被选中: function copyToClipb…

js jquery

js jquery

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够…

js实现vue路由

js实现vue路由

Vue 路由的基本实现 在 Vue.js 中实现路由功能通常使用 Vue Router 库。Vue Router 是 Vue.js 官方的路由管理器,用于构建单页面应用(SPA)。 安装 Vue R…

js实现滚动

js实现滚动

实现滚动效果的方法 在JavaScript中实现滚动效果可以通过多种方式完成,以下是一些常见的方法: 使用window.scrollTo() window.scrollTo()方法可以将页面滚动到指…

js进度条实现

js进度条实现

使用HTML和CSS创建基础结构 在HTML中创建一个容器元素用于显示进度条,通常使用<div>元素。CSS用于设置进度条的样式,包括宽度、高度、颜色和圆角等属性。 <div cl…

vue 怎么实现上传

vue 怎么实现上传

Vue 实现文件上传的方法 使用原生 HTML5 文件上传 通过 <input type="file"> 元素结合 Vue 的数据绑定实现基础文件上传功能。 <template&g…