vue实现大文件切片上传

在前端上传 大文件(比如几百 MB 或几 GB 时,一般会用 文件切片(chunk upload)+ 断点续传 的方式。核心思路是:

  1. 前端把文件 按固定大小切成多个 chunk
  2. 逐个上传 chunk
  3. 服务端 按顺序合并 chunk
  4. 如果中断,可以 只上传缺失的 chunk

一、实现流程(大文件切片上传)

流程通常是:

复制代码
选择文件
   ↓
计算文件hash(可选,用于秒传)
   ↓
切片 file.slice()
   ↓
并发上传 chunk
   ↓
服务端记录 chunk
   ↓
全部上传完成
   ↓
请求服务端 merge

常见参数:

复制代码
chunkIndex   当前分片序号
chunkSize    分片大小
totalChunks  分片总数
fileHash     文件hash

二、Vue 实现案例

1 选择文件

html 复制代码
<input type="file" @change="handleFileChange" />
js 复制代码
data() {
  return {
    file: null
  }
},
methods: {
  handleFileChange(e) {
    this.file = e.target.files[0]
  }
}

三、文件切片

假设每片 5MB

js 复制代码
const CHUNK_SIZE = 5 * 1024 * 1024

function createChunks(file) {
  const chunks = []
  let start = 0

  while (start < file.size) {
    chunks.push(file.slice(start, start + CHUNK_SIZE))
    start += CHUNK_SIZE
  }

  return chunks
}

返回:

复制代码
[chunk0, chunk1, chunk2 ...]

四、上传切片

js 复制代码
async uploadFile() {

  const chunks = createChunks(this.file)

  const requests = chunks.map((chunk, index) => {

    const formData = new FormData()

    formData.append("file", chunk)
    formData.append("index", index)
    formData.append("fileName", this.file.name)
    formData.append("total", chunks.length)

    return fetch("/upload", {
      method: "POST",
      body: formData
    })

  })

  await Promise.all(requests)

  await this.mergeChunks()

}

五、通知服务端合并

js 复制代码
async mergeChunks() {

  await fetch("/merge", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      fileName: this.file.name
    })
  })

}

六、服务端逻辑(核心思路)

无论你是用 Node.js / Java / Go,都一样。

上传 chunk

复制代码
/upload

保存为

复制代码
/upload
   fileHash/
       0
       1
       2
       3

合并文件

复制代码
/merge

伪代码

js 复制代码
for (let i = 0; i < total; i++) {
  读取 chunk i
  append 到最终文件
}

七、优化(生产级必须做)

1 并发控制(避免100个请求)

推荐 5~10 并发

js 复制代码
async function uploadChunks(chunks, limit = 5) {

}

2 文件 hash(实现秒传)

使用

复制代码
spark-md5

计算 hash

js 复制代码
hash = md5(file)

服务器如果存在

复制代码
直接返回 秒传成功

3 断点续传

流程:

  1. 上传前询问服务器

    /check

返回

复制代码
已上传 chunks = [0,1,4,5]
  1. 前端只上传

    [2,3]


4 上传进度

js 复制代码
xhr.upload.onprogress = (e)=>{
  progress = e.loaded / e.total
}

八、完整 Vue 示例(简化版)

js 复制代码
async uploadFile() {

  const CHUNK_SIZE = 5 * 1024 * 1024
  const file = this.file

  const chunks = []
  let start = 0

  while (start < file.size) {
    chunks.push(file.slice(start, start + CHUNK_SIZE))
    start += CHUNK_SIZE
  }

  for (let i = 0; i < chunks.length; i++) {

    const formData = new FormData()

    formData.append("file", chunks[i])
    formData.append("index", i)
    formData.append("total", chunks.length)
    formData.append("fileName", file.name)

    await fetch("/upload", {
      method: "POST",
      body: formData
    })

  }

  await fetch("/merge", {
    method: "POST",
    body: JSON.stringify({ fileName: file.name })
  })

}
相关推荐
暗冰ཏོ10 小时前
VUE面试题大全
前端·javascript·vue.js·面试
雨雨雨雨雨别下啦14 小时前
心理健康AI助手 - 项目总结
前端·javascript·vue.js·人工智能·信息可视化
风之舞_yjf14 小时前
Vue基础(32)_TodoList案例
前端·javascript·vue.js
程序软件分享17 小时前
vue多语言交易所系统/期货/合约交易/质押生息/盲盒/挖矿/跟单源码
前端·javascript·vue.js·期货平台源码
Rooting++18 小时前
package.json三种依赖的区别
vue.js·json
Yeh20205818 小时前
springboot+vue笔记
vue.js·spring boot·笔记
m0_7510186619 小时前
docker 安装 nginx
vue.js·nginx·docker
zyl8372119 小时前
3Dmol.js + Vue3快速上手
vue.js
镜宇秋霖丶20 小时前
2026.5.18@霖宇博客制作中遇见的问题
vue.js
w_t_y_y20 小时前
VUE3(二)VUE2和VUE3区别
前端·javascript·vue.js