当前位置:首页 > VUE

vue实现切片上传

2026-01-18 12:54:00VUE

切片上传的实现原理

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

前端实现步骤

使用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并发上传所有切片。
  • 合并请求:所有切片上传完成后,发送合并请求通知服务端。

服务端处理逻辑

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

vue实现切片上传

  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为宜。
  • 服务端临时目录需要定期清理未合并的切片。
  • 合并文件时注意内存限制,大文件建议使用流式合并。

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

相关文章

jquery 上传

jquery 上传

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

Vue实现图片批量上传

Vue实现图片批量上传

Vue 图片批量上传实现方法 准备工作 安装必要依赖(如axios、element-ui等),确保项目基于Vue 2/3环境。以Vue 3 + Element Plus为例: npm install…

react实现录制视频上传

react实现录制视频上传

实现视频录制与上传的基本流程 使用React实现视频录制并上传需要结合浏览器提供的媒体API和HTTP上传功能。以下是关键步骤: 获取用户摄像头权限 使用navigator.mediaDevices…

php实现上传进度条

php实现上传进度条

PHP 文件上传进度条实现方法 在PHP中实现文件上传进度条需要结合前端和后端技术,以下是一种常见的实现方案: 使用 session.upload_progress 功能 PHP 5.4+ 内置了上…

js实现上传进度条

js实现上传进度条

使用XMLHttpRequest实现上传进度条 XMLHttpRequest是传统的AJAX请求方式,支持上传进度监控。通过监听upload对象的progress事件获取上传进度信息。 const…

js 实现异步上传

js 实现异步上传

异步上传的实现方法 使用XMLHttpRequest或Fetch API可以实现JavaScript的异步文件上传。以下是两种常见方法: XMLHttpRequest方式 const upload…