当前位置:首页 > VUE

vue实现分段上传

2026-01-14 03:36:07VUE

实现分段上传的基本思路

分段上传(分片上传)是将大文件分割成多个小块分别上传,最后在服务器合并的技术。这种方式能提高上传稳定性、支持断点续传,并减轻服务器压力。

前端实现步骤

安装依赖 需要axios库处理网络请求,可能用到spark-md5计算文件哈希(用于断点续传标识)。

npm install axios spark-md5

文件分片处理 通过JavaScript的File API将文件切割为多个Blob片段。

// 文件分片函数
function createFileChunks(file, chunkSize = 5 * 1024 * 1024) {
  const chunks = []
  for (let i = 0; i < file.size; i += chunkSize) {
    chunks.push(file.slice(i, i + chunkSize))
  }
  return chunks
}

计算文件哈希(可选) 使用spark-md5计算文件唯一标识,用于服务端校验和断点续传。

import SparkMD5 from 'spark-md5'

function calculateFileHash(file) {
  return new Promise(resolve => {
    const spark = new SparkMD5.ArrayBuffer()
    const reader = new FileReader()
    reader.readAsArrayBuffer(file)
    reader.onload = e => {
      spark.append(e.target.result)
      resolve(spark.end())
    }
  })
}

上传分片 通过FormData携带分片数据,建议添加分片索引、总片数等元信息。

async function uploadChunk(chunk, index, fileHash) {
  const formData = new FormData()
  formData.append('chunk', chunk)
  formData.append('index', index)
  formData.append('hash', fileHash)
  formData.append('filename', file.name)

  try {
    await axios.post('/upload', formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    })
  } catch (error) {
    console.error('上传失败:', error)
  }
}

合并请求 所有分片上传完成后,通知服务端合并文件。

function mergeChunks(filename, fileHash, chunkCount) {
  return axios.post('/merge', { filename, fileHash, chunkCount })
}

完整组件示例

<template>
  <div>
    <input type="file" @change="handleFileChange" />
    <button @click="handleUpload">上传</button>
    <div>进度: {{ progress }}%</div>
  </div>
</template>

<script>
import axios from 'axios'
import SparkMD5 from 'spark-md5'

export default {
  data() {
    return {
      file: null,
      progress: 0
    }
  },
  methods: {
    handleFileChange(e) {
      this.file = e.target.files[0]
    },
    async handleUpload() {
      if (!this.file) return

      const chunkSize = 5 * 1024 * 1024 // 5MB
      const chunks = createFileChunks(this.file, chunkSize)
      const fileHash = await calculateFileHash(this.file)

      // 检查已上传分片(断点续传)
      const { data } = await axios.get('/check', {
        params: { hash: fileHash }
      })

      const uploadedChunks = data.uploaded || []
      const requests = chunks.map((chunk, index) => {
        if (uploadedChunks.includes(index)) {
          this.progress += (100 / chunks.length)
          return Promise.resolve()
        }
        return uploadChunk(chunk, index, fileHash)
          .then(() => {
            this.progress += (100 / chunks.length)
          })
      })

      await Promise.all(requests)
      await mergeChunks(this.file.name, fileHash, chunks.length)
    }
  }
}
</script>

服务端注意事项

  1. 临时存储:分片需存储在临时目录,合并后清理
  2. 并发控制:前端可限制并发上传数(如3-5个并行请求)
  3. 断点续传:服务端应记录已接收的分片索引
  4. 合并操作:按分片索引顺序合并文件

优化方向

  • 进度显示:分片上传进度和整体进度分开计算
  • 错误重试:对失败分片自动重试机制
  • 暂停恢复:通过取消axios请求实现暂停功能
  • Web Worker:大文件哈希计算放入Worker线程避免界面卡顿

vue实现分段上传

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

相关文章

vue实现聊天功能

vue实现聊天功能

Vue 实现聊天功能的基本步骤 安装必要依赖 使用 Vue CLI 创建项目后,安装 socket.io-client 或 vue-socket.io 实现实时通信,或基于 HTTP 的 axios…

vue实现自动翻译

vue实现自动翻译

Vue 实现自动翻译的方法 在 Vue 项目中实现自动翻译功能可以通过多种方式完成,以下是几种常见的方法: 使用第三方翻译 API 注册并获取翻译 API 的密钥(如 Google Translat…

vue如何实现放大缩小

vue如何实现放大缩小

Vue实现放大缩小功能的方法 在Vue中实现元素的放大缩小功能,可以通过CSS变换、第三方库或直接操作DOM样式来实现。以下是几种常见的方法: 使用CSS transform属性 通过绑定Vue的…

vue实现页面截屏

vue实现页面截屏

使用html2canvas库实现截屏 html2canvas是一个流行的JavaScript库,可以将DOM元素转换为Canvas图像。在Vue项目中安装html2canvas: npm insta…

vue前端分页怎么实现

vue前端分页怎么实现

前端分页实现方法 在Vue中实现前端分页通常涉及数据分割和页面控制逻辑。以下是常见的实现方式: 使用计算属性分页 通过计算属性对数据进行切片处理: computed: { paginatedD…

vue穿梭框组件实现

vue穿梭框组件实现

实现基础穿梭框组件 在Vue中实现穿梭框组件,可以使用<el-transfer>(Element UI)或手动实现。以下是手动实现的核心逻辑: <template> &l…