当前位置:首页 > VUE

vue实现切片上传

2026-02-19 05:21:39VUE

切片上传实现原理

切片上传的核心是将大文件分割为多个小块(chunk),分批上传到服务器。服务器接收后合并这些切片,最终还原完整文件。这种方式能有效解决大文件上传超时、网络不稳定等问题,并支持断点续传。

前端实现步骤

HTML部分 创建文件选择控件和上传按钮,监听文件选择事件:

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

定义切片方法 通过Blob.prototype.slice方法实现文件分片:

function createChunks(file, chunkSize) {
  const chunks = []
  let start = 0
  while (start < file.size) {
    chunks.push({
      chunk: file.slice(start, start + chunkSize),
      filename: file.name
    })
    start += chunkSize
  }
  return chunks
}

上传逻辑实现 使用FormData携带切片数据,注意添加切片序号和文件hash标识:

vue实现切片上传

async function uploadChunks(chunks) {
  const requests = chunks.map((chunk, index) => {
    const formData = new FormData()
    formData.append('chunk', chunk.chunk)
    formData.append('filename', chunk.filename)
    formData.append('hash', `${fileHash}-${index}`)
    return axios.post('/upload', formData)
  })
  await Promise.all(requests)
}

后端处理要点

接收切片 使用multer等中间件处理文件上传:

app.post('/upload', upload.single('chunk'), (req, res) => {
  const { filename, hash } = req.body
  fs.renameSync(req.file.path, `temp/${hash}`)
  res.send({ status: 'success' })
})

合并切片 当所有切片上传完成后触发合并操作:

vue实现切片上传

function mergeFiles(filename, chunkCount) {
  const writeStream = fs.createWriteStream(`uploads/${filename}`)
  for (let i = 0; i < chunkCount; i++) {
    const chunkPath = `temp/${fileHash}-${i}`
    writeStream.write(fs.readFileSync(chunkPath))
    fs.unlinkSync(chunkPath)
  }
  writeStream.end()
}

优化功能实现

文件哈希生成 使用spark-md5计算文件唯一标识:

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

断点续传支持 上传前检查服务器已存在的切片:

async function checkExistingChunks(fileHash, chunkCount) {
  const { data } = await axios.get('/check', {
    params: { fileHash, chunkCount }
  })
  return data.existedChunks
}

进度显示 利用axios的onUploadProgress回调更新进度:

axios.post('/upload', formData, {
  onUploadProgress: progressEvent => {
    const percent = Math.round(
      (progressEvent.loaded / progressEvent.total) * 100
    )
    console.log(`当前切片上传进度:${percent}%`)
  }
})

完整示例组件

<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 fileHash = await this.calculateHash(this.file)
      const chunks = this.createChunks(this.file, 1024 * 1024) // 1MB每片

      const existedChunks = await this.checkExistingChunks(fileHash, chunks.length)
      const requests = chunks
        .filter((_, index) => !existedChunks.includes(index))
        .map((chunk, index) => this.uploadChunk(chunk, fileHash, index))

      await Promise.all(requests)
      await this.mergeFiles(fileHash, this.file.name)
    },
    // 其他方法实现参考前述代码片段
  }
}
</script>

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

相关文章

vue实现音乐上传

vue实现音乐上传

Vue 实现音乐上传功能 音乐上传功能通常涉及前端界面交互、文件选择、上传进度显示以及后端接口对接。以下是基于 Vue 的实现方法: 前端界面设计 使用 Vue 的模板语法创建一个简单的上传界面,包…

vue实现图片重新上传

vue实现图片重新上传

实现图片重新上传功能 在Vue中实现图片重新上传功能,通常涉及文件选择、预览、上传和重置等步骤。以下是一个完整的实现方案: 模板部分 <template> <div>…

vue实现上传头像显示

vue实现上传头像显示

Vue 实现上传头像并显示 前端实现(Vue 3 + Element Plus) 模板部分 <template> <div class="avatar-upload">…

vue怎么实现头像上传

vue怎么实现头像上传

Vue 实现头像上传的方法 使用 <input type="file"> 获取文件 通过 HTML 的 <input type="file"> 元素让用户选择文件。在 Vue…

react实现录制视频上传

react实现录制视频上传

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

js实现上传进度条

js实现上传进度条

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