返回

突破文件上传限制!Vue切片秒传断点续传代码奉上

前端

前言

在现代互联网应用中,大文件上传是一个常见的需求,但传统的上传方式往往存在速度慢、容易失败等问题。为了解决这些问题,本文将介绍如何使用Vue.js实现大文件上传的功能,包括切片上传、秒传和断点续传。

安装依赖

npm i -S spark-md5

对接API(需后端接口支持)

// 获取分片上传的服务器端地址
const getUploadUrl = () => {
  return axios.get('/api/upload/get-url');
};

// 开始分片上传
const startUpload = (file, sliceSize) => {
  return axios.post('/api/upload/start-upload', {
    fileName: file.name,
    fileSize: file.size,
    sliceSize: sliceSize,
  });
};

// 上传分片
const uploadSlice = (slice, uploadUrl) => {
  return axios.post(uploadUrl, slice, {
    headers: {
      'Content-Type': 'application/octet-stream',
    },
  });
};

// 合并分片
const mergeSlices = (fileName, fileId) => {
  return axios.post('/api/upload/merge-slices', {
    fileName: fileName,
    fileId: fileId,
  });
};

封装切片上传的Mixin

export default {
  data() {
    return {
      file: null,
      sliceSize: 1024 * 1024 * 5, // 5MB
      chunkCount: 0,
      uploadedChunks: 0,
      uploadUrl: null,
      fileId: null,
    };
  },
  methods: {
    // 获取文件分片
    getSlices(file) {
      const slices = [];
      for (let i = 0; i < Math.ceil(file.size / this.sliceSize); i++) {
        const start = i * this.sliceSize;
        const end = Math.min(start + this.sliceSize, file.size);
        slices.push(file.slice(start, end));
      }
      return slices;
    },

    // 开始上传
    async startUpload() {
      try {
        const { data } = await getUploadUrl();
        this.uploadUrl = data.uploadUrl;
        this.fileId = data.fileId;
        this.chunkCount = Math.ceil(this.file.size / this.sliceSize);

        const slices = this.getSlices(this.file);
        for (let i = 0; i < slices.length; i++) {
          await this.uploadSlice(slices[i], this.uploadUrl);
          this.uploadedChunks++;
        }

        await mergeSlices(this.file.name, this.fileId);
        alert('文件上传成功!');
      } catch (error) {
        console.error(error);
        alert('文件上传失败!');
      }
    },

    // 上传分片
    async uploadSlice(slice, uploadUrl) {
      try {
        const { data } = await uploadSlice(slice, uploadUrl);
        if (data.success) {
          this.uploadedChunks++;
        }
      } catch (error) {
        console.error(error);
        alert('分片上传失败!');
      }
    },
  },
};

使用

<template>
  <div>
    <input type="file" @change="fileSelected">
    <button @click="startUpload">上传</button>
  </div>
</template>

<script>
import mixin from './mixin';

export default {
  mixins: [mixin],
  methods: {
    fileSelected(event) {
      this.file = event.target.files[0];
    },
  },
};
</script>

结语

通过本文介绍的大文件上传代码,您将能够轻松实现切片上传、秒传和断点续传等功能,为您的用户带来更流畅、更稳定的上传体验。如果您正在寻找大文件上传的解决方案,不妨尝试使用本文提供的代码,让您的项目更上一层楼!