当前位置:首页 > 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标识:

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' })
})

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

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 实现视频上传功能 安装依赖 确保项目中已安装 axios 或 vue-upload-component 等上传库。通过 npm 安装: npm install axios 前端组件实现 创建…

vue实现上传表格

vue实现上传表格

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

vue实现上传视频

vue实现上传视频

使用 <input type="file"> 实现基础上传 通过 HTML 原生文件选择控件获取视频文件,结合 Vue 处理上传逻辑。 <template> <…

vue实现拖拽上传

vue实现拖拽上传

Vue 拖拽上传实现方法 使用 HTML5 原生拖拽 API 在 Vue 中可以通过监听原生拖拽事件实现基础功能: <template> <div class="dr…

vue实现语音上传

vue实现语音上传

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

vue实现切片上传

vue实现切片上传

切片上传的实现原理 切片上传是将大文件分割成多个小块(切片)分别上传,最后在服务端合并。这种方式能提高上传效率、支持断点续传和并发上传。 前端实现步骤 使用Vue实现切片上传需要借助File对象…