vue实现大文件上传(切片上传)

这篇具有很好参考价值的文章主要介绍了vue实现大文件上传(切片上传)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上传视频的时候,如果视频体积过大,一次性上传就会出现各种问题,或者由于网络不佳的原因导致上传失败,这时候就需要大文件上传的常见方法,如切片上传,顾名思义,切片上传就是将一个大文件切成一份一份的小文件,再去将每一个小文件上传。
首先还是借助iview的Upload上传组件,绑定before-upload(上传文件之前的钩子)获取文件数据,将上传action地址设置为空,并return false取消自动上传。

<Upload
    :show-upload-list="false"
    :on-success="upVideoPicture"
    :before-upload="handeleBeforeUpVideo"
    :action="''"
    :data="contLaunchUrl"
    name="file"
    type="drag"
    style="display: inline-block; width: 150px"
>
   <div style="width: 150px; height: 105px; line-height: 105px">
    <Icon type="ios-camera" size="20"></Icon>
   </div>
   // iview组件 Spin加载中
   <Spin fix v-if="uploadVideoLoading">
      <Icon type="ios-loading" size=18 class="demo-spin-icon-load"></Icon>
   <div>Loading</div>
   </Spin>
</Upload>

在before-upload(上传文件之前的钩子)的函数中可以获取到文件数据,拿到数据开始切片,大小就以1M为例。
注意:上传服务器的文件名称最好设置为英文,中文可能会出现问题,所以我设置名称为时间戳+四位随机数。
时间戳:new Date().getTime()
四位随机数:Math.floor(Math.random()*(9999-1000))+1000

// 文件切片
fileChunk(file){
  let that = this
  // 文件名称设置为时间戳+四位随机数
  let name = new Date().getTime() + '' + (Math.floor(Math.random()*(9999-1000))+1000);
  let fileName = name  // 获取文件名
  let fileType = `${file.name.split('.')[length]}` // 文件类型后缀
  let chunkSize = 1 * 1024 * 1024   // 示例1M
  let chunkList = []  // 创建一个数组用来存储每一片文件流数据
  if (file.size < chunkSize) {  // 如果文件大小小于1M就只有一片,不用切
     chunkList.push(file.slice(0))  // 文件流从第一个字节直接截取到最后就可以了
   } else {  // 如果文件大小大于1M 就需要切片了
     var start = 0, end = 0  // 创建两个变量 开始位置 结束位置
     while (true) {  // 循环
       end += chunkSize  // 结束为止 = 结束位置 + 每片大小
       let blob = file.slice(start, end)  // 文件流从开始位置截取到结束位置
       start += chunkSize  // 截取完,开始位置后移
       if (!blob.size) {  // 如果截取不到了就退出
         break;
       }
       chunkList.push(blob)  // 把截取的每一片数据保存到数组
     }
   }
   that.transformFileType(chunkList,fileName,fileType); // 文件类型转换
  },

以下图片是切片完成后的数据,数据类型为blob
vue大文件上传,vue.js,javascript,前端
由于切完后的数据是blob类型,而我们接口上传需要文件类型,所以需要转换一下文件类型的,这里就根据后端给的接口需要什么类型参数去转换。

// 文件类型转换
async transformFileType(list,name,type){ // list,name,type是上传时需要的参数,可根据情况而定
   let that = this
   let uploadFileNum = 0; // 已经上传的文件数量
   let num = localStorage.getItem("uploadFileNum")?localStorage.getItem("uploadFileNum"):0 // 已经上传文件数量
   // 如果已经全部上传 直接合并
   if(num == list.length) return that.mergeFileFun(name,list.length,type)
   for (var i = num; i < list.length; i++) {
     // 这么写是因为文件转换是异步任务
     let transToFile = async(blob, fileName, fileType) => {
       return new window.File([blob], fileName, {type: fileType})
     }
     // 转换完成后可以将file对象传给接口 fileFormData 是需要传递的参数
     let fileFormData = new FormData();
     const transToFileRes = await transToFile(list[i], "video", type)
     fileFormData.append('file',transToFileRes)
     fileFormData.append('fileName',name)
     fileFormData.append('fileNum',Number(i)+1)
     fileFormData.append('filePath','/video')
     await that.uploadFileMethods(fileFormData,i,name,list,type) // 上传文件
   }
},

数据类型转换完成后就可以调上传视频的接口了,再上传文件成功后往缓存里设置一个已上传文件数量标识,如遇到网络不佳,没有及时全部上传成功可利用这个标识找到没有上传的部分继续上传,加快上传速度。
cookie,sessionStorage,localStorage区别
有效时间:cookie在关闭浏览器后失效,sessionStorage在关闭页面后失效,localStorage需要手动清除才会失效;
数据存储大小:cookie只有4K左右,sessionStorage和LocalStorage一般有5M。
cookie会在请求头中一起发送给服务器,另外两个则不参与通信。

// 上传文件
async uploadFileMethods(fileFormData,uploadFileNum,name,list,type) {
  let that = this
  const instance = axios.create({
    withCredentials: true
  })
  await instance({
    url: this.uploadFile, // 上传文件地址
    method: 'POST',
    data: fileFormData,
  }).then(res => {
    // console.log(res,"res文件上传")
    if(res.data.code != 200){
      that.uploadVideoLoading = false;
      that.$Message.error(res.data.message);
    }
    uploadFileNum = Number(uploadFileNum) + 1
    localStorage.setItem("uploadFileNum", uploadFileNum); // 已经上传文件数量
    // 如果已经上传数量uploadFileNum与切片长度一致,就开始合并文件
    if(uploadFileNum == list.length){
      that.mergeFileFun(name,list.length,type);
    }
  })
},

上传完成后调用合并文件的接口,在合并完成后,清除标记。文章来源地址https://www.toymoban.com/news/detail-703953.html

// 合并文件
 mergeFileFun(name,fileNo,type){
   let that = this
   let fileFormData = new FormData(); // 合并文件接口参数
   fileFormData.append('fileName',name) // 合并的该套文件的文件名
   fileFormData.append('fileTotalNum',fileNo) // 该套文件总数量
   fileFormData.append('fileSuffix',type) // 文件类型后缀
   fileFormData.append('filePath','/video') // 该套文件存放一级路径
   const instance = axios.create({
     withCredentials: true
   })
   instance({
     url: this.mergeFile, // 合并文件地址
     method: 'POST',
     data: fileFormData,
   }).then(res => {
     if(res.data.code != 200){
       that.uploadVideoLoading = false;
       that.$Message.error(res.data.message);
     }
     that.uploadVideoLoading = false;
     let fileUrl = res.data.message;  // 后端返回的文件路径
     localStorage.removeItem('uploadFileNum') // 合并成功后清除已经上传文件数量标记
   })
 },

到了这里,关于vue实现大文件上传(切片上传)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一次理清前端文件上传操作(单个,多个,大文件切片)

    相信大家在工作中也会遇到前端文件上传的需求,虽然已经在项目中使用FormData和elementUI中upload组件都实现过类似上传效果,但自己对这块一直一知半解,因此做一个笔记梳理一下前端方面的文件上传操作,以供日常参考。 总体来说常用的两种方式:二进制传输和base64格式直

    2024年02月03日
    浏览(47)
  • vue+ts大文件切片上传

    别看文字了,看代码注释吧§(* ̄▽ ̄*)§ 1. src 下 的.vue 文件 src/APP.vue 2. src下文件夹,与上方👆代码在同一目录 src/utils/index.ts 3.效果图   非常简单(。・ω・。) 

    2024年01月23日
    浏览(35)
  • vue 大文件视频切片上传处理方法

    前端上传大文件、视频的时候会出现超时、过大、很慢等情况,为了解决这一问题,跟后端配合做了一个切片的功能。 我这个切片功能是基于 minion 的,后端会把文件放在minion服务器上。具体看后端怎么做 1、在项目的 util(这个文件夹是自己创建的,如果项目里没有可以自行

    2024年02月13日
    浏览(47)
  • JS-27 前端数据请求方式;HTTP协议的解析;JavaScript XHR、Fetch的数据请求与响应函数;前端文件上传XHR、Fetch;安装浏览器插件FeHelper

    早期的网页都是通过后端渲染来完成的,即服务器端渲染(SSR,server side render): 客户端发出请求 - 服务端接收请求并返回相应HTML文档 - 页面刷新,客户端加载新的HTML文档; 服务器端渲染的缺点: 当用户点击页面中的某个按钮向服务器发送请求时,页面本质上只是一些数

    2024年02月16日
    浏览(57)
  • 【Java实现文件上传】java后端+vue前端实现文件上传全过程详解(附源码)

    【 写在前面 】其实这篇文章我早就想写了,只是一直被需求开发耽搁,这不晚上刚好下班后有点时间,记录一下。需求是excel表格的上传,这个是很多业务系统不可或缺的功能点,再此也希望您能够读完我这篇文章对文件上传不再困惑。(文件下载见另外一篇) 涉及知识点

    2024年02月06日
    浏览(46)
  • vue前端实现上传文件的两种方式

    1.使用form表单的形式 第一种方式就是使用FormData的方式进行上传 html代码: JS代码: 2.使用element-ui的el-upload的方式进行上传 这里我是根据需求封装了一个组件

    2024年02月11日
    浏览(37)
  • Spring Boot + MinIO 实现文件切片极速上传技术

    🎉欢迎来到SpringBoot框架学习专栏~ ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:SpringBoot 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,如果文中出现错误,希望大家能指

    2024年02月04日
    浏览(51)
  • 应用开发平台前端集成vue-simple-uploader实现文件分块上传

    文件的上传是系统的必备功能,Element提供了上传组件upload,也基本能满足常见常用的文件上传功能,特别是应对小型文件(10M以下)的处理。但如果是遇到要求更多更高的场景,上传几百兆甚至上G的视频文件,要求分块上传,能断点续传,显示进度,能暂停,能重试……这

    2024年02月08日
    浏览(42)
  • 大文件切片上传+断点续传解决方案-前后端实现(附源码)

    上传文件大家应该都做过,前端直接把file文件传给后端就ok了,但是大文件这样传就会造成页面假死,体验极差。如果遇到网络不稳定的时候,中途上传失败的话,又要从头开始传,本来文件就大,还慢。所以今天我们用一种新方法-切片上传+断点续传 页面上很简单,我就放

    2024年02月09日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包