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

}
相关推荐
daols881 小时前
vxe-table 渲染器教程一:实现金额输入控件
javascript·vue.js·vxe-table
不好听6132 小时前
React vs Vue:两大前端框架技术选型深度对比
前端·vue.js·react.js
腻害兔3 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
腻害兔5 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程
Larcher10 小时前
LangChain RAG 排错实录:.env 为什么没有生效
vue.js·后端
一个写前端的11 小时前
基于 Vue 3 的大文件分片上传组件,支持断点续传、并发上传、失败重试等功能
前端·javascript·vue.js
活于未来11 小时前
从零搭建期权波动率曲面可视化平台:FastAPI + Vue 3 实战
vue.js
橘子海全栈攻城狮12 小时前
【最新源码】基于SpringBoot + Vue的超市管理系统的设计与实现D002
java·开发语言·vue.js·spring boot·后端·spring
Cobyte15 小时前
使用 JavaScript 实现有限状态机的经典问题
前端·javascript·vue.js
acheding15 小时前
File System Access API 实战:让网页真正读写本地文件
前端·javascript·vue.js·编辑器·markdown