当前位置:首页 > VUE

vue实现切片上传

2026-01-18 12:54:00VUE

切片上传的实现原理

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

vue实现切片上传

前端实现步骤

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

vue实现切片上传

<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 中实现上传表格功能,通常涉及文件上传、文件解析(如 Excel 或 CSV)以及数据展示。以下是具体实现方法: 使用 Element UI 上传组件 Element…

vue实现上传表格

vue实现上传表格

Vue实现上传表格的方法 使用Element UI上传组件 Element UI提供了el-upload组件,可以方便地实现文件上传功能。需要安装Element UI并引入相关组件。 安装Eleme…

vue实现语音上传

vue实现语音上传

实现语音上传功能 在Vue中实现语音上传功能需要结合浏览器的Web Audio API和文件上传逻辑。以下是一个完整的实现方案: 录音功能实现 安装依赖库recorder-core和wav编码器:…

vue实现附件上传

vue实现附件上传

文件上传的基本实现 在Vue中实现文件上传可以通过原生HTML的<input type="file">元素结合Vue的数据绑定和事件处理来完成。创建一个文件上传组件,监听change事件获…

vue实现视频上传

vue实现视频上传

Vue 实现视频上传的方法 使用原生 input 元素和 FormData 在 Vue 中可以通过原生 input 元素结合 FormData 实现视频上传功能。创建一个文件选择输入框,监听文件变化事…

vue java实现分片上传

vue java实现分片上传

分片上传的实现原理 分片上传是将大文件分割成多个小块分别上传,最后在服务器合并的技术。这种方式能解决大文件上传超时、网络不稳定等问题,同时支持断点续传。 前端Vue实现 前端需要使用File API…