当前位置:首页 > VUE

vue实现切片上传

2026-01-18 12:54:00VUE

切片上传的实现原理

切片上传是将大文件分割成多个小块(切片)分别上传,最后在服务端合并。这种方式能提高上传效率、支持断点续传和并发上传。

vue实现切片上传

前端实现步骤

使用Vue实现切片上传需要借助File对象的slice方法分割文件,配合axiosfetch发送请求。

<template>
  <input type="file" @change="handleFileChange" />
  <button @click="uploadFile">上传</button>
</template>

<script>
export default {
  data() {
    return {
      file: null,
      chunkSize: 2 * 1024 * 1024, // 2MB每片
    };
  },
  methods: {
    handleFileChange(e) {
      this.file = e.target.files[0];
    },
    async uploadFile() {
      if (!this.file) return;

      const chunks = this.createChunks(this.file);
      await this.uploadChunks(chunks);
    },
    createChunks(file) {
      const chunks = [];
      let start = 0;
      while (start < file.size) {
        const end = Math.min(start + this.chunkSize, file.size);
        chunks.push({
          chunk: file.slice(start, end),
          index: chunks.length,
          total: Math.ceil(file.size / this.chunkSize),
          filename: file.name,
        });
        start = end;
      }
      return chunks;
    },
    async uploadChunks(chunks) {
      const requests = chunks.map((item) => {
        const formData = new FormData();
        formData.append('chunk', item.chunk);
        formData.append('index', item.index);
        formData.append('total', item.total);
        formData.append('filename', item.filename);

        return axios.post('/upload', formData, {
          headers: { 'Content-Type': 'multipart/form-data' },
        });
      });

      await Promise.all(requests);
      this.mergeChunks();
    },
    async mergeChunks() {
      await axios.post('/merge', {
        filename: this.file.name,
        total: Math.ceil(this.file.size / this.chunkSize),
      });
    },
  },
};
</script>

关键点说明

  • 文件分割:通过File.prototype.slice方法将文件切割成指定大小的块。
  • 并发上传:使用Promise.all并发上传所有切片。
  • 合并请求:所有切片上传完成后,发送合并请求通知服务端。

服务端处理逻辑

服务端需要实现两个接口:

  1. 接收切片并临时存储
  2. 合并所有切片为完整文件
// Node.js示例(Express框架)
const express = require('express');
const fs = require('fs');
const multer = require('multer');
const path = require('path');

const app = express();
const upload = multer({ dest: 'temp/' });

app.post('/upload', upload.single('chunk'), (req, res) => {
  const { index, filename } = req.body;
  const chunkPath = path.join('temp', `${filename}-${index}`);
  fs.renameSync(req.file.path, chunkPath);
  res.send({ success: true });
});

app.post('/merge', async (req, res) => {
  const { filename, total } = req.body;
  const filePath = path.join('uploads', filename);
  const writeStream = fs.createWriteStream(filePath);

  for (let i = 0; i < total; i++) {
    const chunkPath = path.join('temp', `${filename}-${i}`);
    const chunk = fs.readFileSync(chunkPath);
    writeStream.write(chunk);
    fs.unlinkSync(chunkPath);
  }

  writeStream.end();
  res.send({ success: true });
});

优化方向

  • 进度显示:通过axiosonUploadProgress回调实现上传进度显示。
  • 断点续传:记录已上传的切片索引,下次上传时跳过。
  • 错误重试:对失败的请求进行自动重试。
  • 文件校验:上传前后通过MD5校验文件完整性。

注意事项

  • 切片大小需根据网络状况调整,通常2-5MB为宜。
  • 服务端临时目录需要定期清理未合并的切片。
  • 合并文件时注意内存限制,大文件建议使用流式合并。

vue实现切片上传

标签: 切片上传
分享给朋友:

相关文章

vue 实现上传

vue 实现上传

Vue 实现文件上传 使用 Vue 实现文件上传可以通过原生 HTML 的 <input type="file"> 或第三方库(如 axios、vue-upload-component)完…

vue实现文档上传

vue实现文档上传

Vue 实现文档上传的方法 使用原生 HTML 表单和 Vue 处理文件上传 在 Vue 中可以通过原生 HTML 的 <input type="file"> 元素结合 Vue 的数据绑定…

vue实现上传

vue实现上传

Vue 实现文件上传 在 Vue 中实现文件上传功能可以通过原生 HTML5 的 <input type="file"> 元素结合 Vue 的数据绑定和事件处理来实现。以下是几种常见的实现…

jquery 上传

jquery 上传

jQuery 文件上传方法 使用 jQuery 实现文件上传可以通过多种方式完成,以下是常见的几种方法: 使用原生表单和 AJAX 创建一个包含文件输入的表单,并通过 jQuery 的 AJA…

jquery上传

jquery上传

jQuery 文件上传的实现方法 jQuery 可以通过多种方式实现文件上传功能,以下介绍几种常见的方法: 使用原生表单和 AJAX 通过 HTML 表单结合 jQuery 的 AJAX 功能实现…

vue实现分段上传

vue实现分段上传

实现分段上传的基本思路 分段上传(分片上传)是将大文件分割成多个小块分别上传,最后在服务器合并的技术。这种方式能提高上传稳定性、支持断点续传,并减轻服务器压力。 前端实现步骤 安装依赖 需要axi…