首页 > 其他分享 >前端如何实现大文件上传

前端如何实现大文件上传

时间:2023-11-17 12:31:40浏览次数:37  
标签:文件 return 前端 file const 上传 size

在开发过程中,经常会遇到一些较大文件上传,如果只使用一次请求去上传文件,一旦这次请求中出现什么问题,那么无论这次上传了多少文件,都会失去效果,用户则需要重新上传所有资源。所以就想到一种方式,将一个大文件分成多个小文件,这样通过多个请求实现大文件上传。

接下来我们就来看看具体是怎么实现的~


<input type="file" id="update-btn">

  <script>

    const updateInput = document.querySelector('#update-btn')

    updateInput.onchange = () => {

      const file = updateInput.files[0]

      if(!file){

        return

      }

    // 通过file的slice 方法可以将文件进行分割,第一个参数是从哪个字节开始,第二个参数是到哪个字节结束

      const chunk = file.slice(0,2000) 

  }

  </script>


这时候我们在控制台可以得到 chunk 是

前端如何实现大文件上传_上传

 这时,我们知道了如何将大文件进行切片,那么我们就创建个函数用于对文件进行切片


const updateInput = document.querySelector('#update-btn')

    updateInput.onchange = () => {

      const file = updateInput.files[0]

      if(!file){

        return

      }

      const chunkList = chunkFileFun(file, 1*1024*1024)

    }

    /**

    * @description: 文件分片函数

    * @param {

    *   file: 需要分片的文件,

    *   size: 文件按照每片多大去分片

    * }

    * @return: [] 文件分片后的数组

    */

    const chunkFileFun = ( file, size ) => {

      const result = []

      for (let i = 0; i < file.size; i += size) {

        result.push(file.slice( i, i + size))

      }

      return result

    }

 这时候我们可以看控制台,我们已经获取到了分片的数组

前端如何实现大文件上传_spark_02

 

这样就结束了吗?并没有~ 如果我们再上传到一半的时候失败了,我们并希望下次上传文件重新上传,我们希望通过和服务器交互知道我们上次上传文件上传到哪里,我们从没有上传的切片继续上传就好了,那么这个东西我们应该如何实现呢?

我在这里使用的是spark-md5这个插件生成一个固定的hash值。大家也可以使用其他方式生成固定的hash值,我们上传的时候通过这个hash值,和服务端交互确认我们上传的是哪个文件上传到哪里,这样就可以解决我们的问题了


<script type="text/javascript" src="./spark-md5.min.js"></script>

  <input type="file" id="update-btn">

  <script>

    const updateInput = document.querySelector('#update-btn')

    updateInput.onchange = async () => {

      const file = updateInput.files[0]

      if (!file) {

        return

      }

      console.log('file', file)

      const chunkList = chunkFileFun(file, 1 * 1024 * 1024)

      console.log('chunkList', chunkList)

      const hash = await getHash(chunkList)

    }

    /**

    * @description: 获取文件hash

    * @param {file: 文件}

    * @return: hash

    */

    const getHash = (chunkList) => {

      const spark = new SparkMD5()

      return new Promise(resolve => {

        const chunkHash = (i) => {

          if (i >= chunkList.length) {

            resolve(spark.end())

            return

          }

          const blob = chunkList[i]

          const read = new FileReader()

          read.onload = e => {

            // 读取到的字节数量

            const byte = e.target.result

            spark.append(byte)

            chunkHash(i + 1)

          }

          read.readAsArrayBuffer(blob)

        }

        chunkHash(0)

      })

    }

    /**

    * @description: 文件分片函数

    * @param {

    *   file: 需要分片的文件,

    *   size: 文件按照每片多大去分片

    * }

    * @return: [] 文件分片后的数组

    */

    const chunkFileFun = (file, size) => {

      const result = []

      for (let i = 0; i < file.size; i += size) {

        result.push(file.slice(i, i + size))

      }

      return result

    }

  </script>

 在这个计算hash过程中需要读取整个文件的内容,这个过程时间会很长,我们一般不会在主线程做这个事,以免页面卡死,我们可以通过web worker,开辟另外一个线程去做这个事情。


参考文章:http://blog.ncmem.com/wordpress/2023/10/10/前端如何实现大文件上传/




标签:文件,return,前端,file,const,上传,size
From: https://blog.51cto.com/u_14023400/8439874

相关文章

  • Git与Gitee的交互及配置忽略文件
    将本地项目提交到Gitee1、创建一个新的仓库:首先,在Gitee上创建一个新的仓库。2、初始化本地项目为Git仓库:这将在项目目录中创建一个名为".git"的隐藏文件夹,用于存储Git的相关配置和版本信息。gitinit3、将项目文件添加到暂存区:执行以下命令将项目文件添加到Git的暂存区:   ......
  • HTML5中怎么实现文件断点续传功能
    HTML5中怎么实现文件断点续传功能,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。断点续传原理目前比较常用的断点续传的方法有两种,一种是通过websocket接口进行文件上传,另一种是通过ajax,两种方法各有千秋......
  • 大文件断点续传上传
    最近接到一个新的需求,需要上传2G左右的视频文件,用测试环境的OSS试了一下,上传需要十几分钟,再考虑到公司的资源问题,果断放弃该方案。一提到大文件上传,我最先想到的就是各种网盘了,现在大家都喜欢将自己收藏的「小电影」上传到网盘进行保存。网盘一般都支持断点续传和文件秒传功能,减少......
  • 通过Java实现文件断点续传功能
    用户上传大文件,网络差点的需要历时数小时,万一线路中断,不具备断点续传的服务器就只能从头重传,而断点续传就是,允许用户从上传断线的地方继续传送,这样大大减少了用户的烦恼。本文将用Java语言实现断点续传,需要的可以参考一下什么是断点续传用户上传大文件,网络差点的需要历时数小时,万......
  • webuploader实现大文件断点续传
    前端代码(基于Yii框架,逻辑可供参考)   <script>    varfileMd5; //文件MD5    varfileObj; //文件对象    varstate='pending'; //状态    WebUploader.Uploader.register({      "before-send":"beforeSend......
  • 未预编译文件“/default.aspx”,因此不能请求该文件
    未预编译文件“/default.aspx”,因此不能请求该文件。说明:执行当前Web请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。异常详细信息:System.Web.HttpException:未预编译文件“/default.aspx”,因此不能请求该文件。 ......
  • 相机突然断电,保存的DAT视频文件如何修复
    3-7本文主要解决因相机突然断电导致拍摄的视频文件损坏的问题。在平常使用相机拍摄视频,比如用单反相机、无人机拍摄视频的时候,如果电池突然断电,或者突然炸机了,就非常有可能会得到一个损坏的视频文件,比如会产生下图中左边的这种文件,这种文件打不开,如果你是做生意的,比如搞婚庆拍摄的,......
  • 电脑版微信图片保存在哪个文件夹,如何一次性全选保存
     8-7电脑版的微信聊天,接收到图片后,会保存到微信的个人数据文件夹中,但是有个问题是这些图片都是加密保存的,普通情况下,确实无法人工去取出来,但是下面有方法可以快速将这些图片在脱离微信的情况下,批量取出来。首先是基础信息获取一、首页找到微信的个人数据文件夹,在电脑版微信登录后,......
  • VS Code中C开发多源文件的编译设置
    1.引言C开发中,通常需要编译多个文件,本文将简要介绍在VSCode中进行C开发时如何编译多个文件。实例工程结构如图所示:其中,main.c文件内容如下:#include"stdio.h"/*Includings*/#include"umath.h"#include"ucmplx.h"intmain(void){/*Testumath.c*/floa......
  • [EFI]Surface Pro 4电脑 Hackintosh 黑苹果引导文件
    硬件型号驱动情况主板SurfacePro4处理器IntelCorei5-6300U2.5GHz已驱动内存16GBDDR42400Mhz已驱动硬盘SamsungSSD860EVO250GMedia(InstallonSSDExternal)已驱动显卡IntelHDGraphics5202GBmacOS13以上自行添加显卡补丁声卡RealtekALC3269(id3)已驱动网卡无无无......