前端使用 切片 实现大文件上传

1、准备好一个简单的上传结构


<template>
  <el-upload
    class="upload-demo"
    action="#"
    :http-request="onHttpRequest"
  >
  <el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</template>

<script>
export default {
  data () {
    return {

    }
  },

  created () {

  },

  methods: {
    onHttpRequest () {
      console.log(123)
    }
  }
}
</script>

2、把对象分割成多个文件流切片;固定数量 && 固定大小

onHttpRequest ({ file }) {
  console.log(file.size)
  // 每块大小
  const chunkSize = 5 * 1024
  // 切割次数
  const chunkCount = Math.ceil(file.size / chunkSize)
  // 文件切片 不是数组的slice 文件对象原型上的slice方法,继承自 Blob的slice 二进制数据
  // 创建一个FormData对象来存储文件片段和相关信息
  const formData = new FormData()
  for (let i = 0; i < chunkCount; i++) {
    formData.append('chunks', file.slice(i * chunkSize, i * chunkSize + chunkSize), '123')
  }
  this.uploadChunk(formData)
},

3、断点续传

// 切片上传
async uploadChunk (formData) {
  const chunk = formData.get('chunks', this.selectChunks)
  await axios({
    method: 'POST',
    url: '/upload',
    data: chunk
  })
  this.selectChunks++
  this.uploadChunk(formData)
}

4、合并文件

if (!chunk && this.selectChunks >= formData.getAll('chunks').length) {
  await axios({
    method: 'GET',
    url: '/merge'
  })
  return
}

5、文件秒传

文件秒传和文件续传不同,文件续传为继续上一次进行上传,而文件秒传为,上传过的文件或者文件切片后端通过标识对比,省略文件传输,如何生成文件标记和文件块标记?文件名字、索引都不是唯一值,真正唯一的是文件内容,所需要根据文件内容生成文件hash,借助spark-md5

5.1 安装 yarn add spark-md5

yarn add spark-md5

5.2 引入和使用

import SparkMd5 from 'spark-md5'
// 创建spark实例
const spark = new SparkMd5.ArrayBuffer()
// 将buffer数据处理为hash
spark.append(buffer)
// 返回hash
const hash = spark.end()

5.3 封装文件的方法

fileParse (file) {
  return new Promise(resolve => {
  // 创建读取文件的实例对象
    const fileReade = new FileReader()
    // 借助实例对象的方法读取文件流数据
    fileReade.readAsArrayBuffer(file)
    // 监听文件流数据读取成功的回调
    fileReade.onload = res => {
    // res.target.result 就是文件流数据
      resolve(res.target.result)
    }
  })
},

5.4 封装获取 hash 方法

async getFileHash (file) {
  const buffer = await this.fileParse(file)
  // 创建spark实例
  const spark = new SparkMd5.ArrayBuffer()
  // 将buffer数据处理为hash
  spark.append(buffer)
  // 返回hash
  return spark.end()
},

5.5 添加 hash 

async onHttpRequest ({ file }) {
  const fileHash = await this.getFileHash(file)
  // 每块大小
  const chunkSize = 5 * 1024
  // 切割次数
  const chunkCount = Math.ceil(file.size / chunkSize)
  // 文件切片 不是数组的slice 文件对象原型上的slice方法,继承自 Blob的slice 二进制数据
  // 创建一个FormData对象来存储文件片段和相关信息
  const formData = new FormData()
  for (let i = 0; i < chunkCount; i++) {
    const chunk = file.slice(i * chunkSize, i * chunkSize + chunkSize)
    const chunkHash = await this.getFileHash(file)
    formData.append('chunks', chunk, `${fileHash}:${chunkHash}`)
  }
  console.log(formData.getAll('chunks'))
  // this.uploadChunk(formData)
},

5.6 文件检查

// 文件检查
async checkFileExists (fileHash) {
  return axios({
    url: '/fileexists?hash=' + fileHash
  })
},
const fileHash = await this.getFileHash(file)
await checkFileExists()

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
引用\[1\]中的代码是一个分页器组件的示例,其中使用了Vue.js和Element UI库来实现。该组件包含了上一页、下一页、总页数等功能,并通过v-for指令和数组来渲染中间的连续页码部分。 引用\[2\]中的代码是一个使用Express框架搭建的后端服务器,用于处理前端发送的请求并返回数据。其中通过读取一个名为images.json的文件来获取数据,并根据前端递的pageNo和pageSize参数进行分页处理,最后将分页后的数据返回给前端。 引用\[3\]中的代码是一个Vue组件的示例,该组件包含了一个图片列表和一个自定义的分页器组件。在created钩子函数中,通过调用img方法来获取图片数据,并将数据赋值给imgs和total变量。同时,该组件还定义了一个getPages方法,用于处理分页器递的当前页数,并通过调用img方法来更新图片数据。 综上所述,要实现文件切片的代码,你可以参考以上示例代码,并根据具体需求进行相应的修改和扩展。 #### 引用[.reference_title] - *1* *2* *3* [不用element-ui你会写分页器吗,并实现分段数据请求](https://blog.csdn.net/m0_51311990/article/details/127601162)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值