松鼠的博客

导航

原生JS实现大文件分片

为了实现断点续传,研究了js的文件分片

实现断点续传的步骤

  • 文件分片按顺序上传,上传第一个后文件名md5加密保存到rdis的key,value保存为上传的index,
  • 然后下面每次上传成功就更新对应的value,保持最新的
  • 第一次上传时,查询redis是否已经存在相同的key,如果相同就跳到保存的index的下一个上传
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <div>
      <!-- 获取文件 -->
      <input type="file" name="选择文件" id="file-upload" />
      <!-- 点击执行 -->
      <input type="button" value="确定" onclick="update(0)" />
      <br />
      <input type="text" id="显示" />
    </div>

    <script>
      // 切片大小
      const chunkSize = 1024 * 1024 * 1 // 确定分片大小
      const xml = new XMLHttpRequest() // ajax请求
      function update(index) {
        // index是上传标记的序列
        const file = document.getElementById('file-upload').files[0] // 获取文件
        console.log('file', file)
        
        // 获取文件的名字和拓展名
        const lastPoint = file.name.lastIndexOf('.')
        const filename = file.name.slice(0, lastPoint)
        const ext = file.name.slice(lastPoint + 1)
        console.log('filename', filename)
        console.log('ext', ext)
        const star = index * chunkSize // 切片的起点
        // 判断起点是否已经超过文件的长度,超过说明已经
        if (star > file.size) {
          return
        }

        const bool = file.slice(star, star + chunkSize) // slice(分割起点,分割终点)是js切割文件的函数,
        console.log('bool', bool)
        const boolname = `${filename}-${index}-${ext}`
        console.log('boolname', boolname)
        const boolfile = new File([bool], boolname) // 把分割后的快转成文件传输
        console.log('boolfile', boolfile)
        const from = new FormData() //定义集合方便后端接收

        from.append('index', index)
        from.append('chunkSize', chunkSize)
        from.append('name', file.name)
        from.append('file', boolfile)
        console.log('from', from)
        xml.open('post', '/接收文件', true) // 发送请求
        xml.send(from) //携带集合
        xml.onreadystatechange = function () {
          if (this.readyState === 4 && this.status === 200) {
            //alert(this.responseText)
            if (this.responseText === '上传完成') {
              //按顺序上传,只有上一片上传成功下一个才能上传
              //这里可以加个判断,获取断点,获取后下一个,后端也会判断切片是否已经下载过
              update(++index)
              document.getElementById('显示').value = star / file.size //显示上传的进度
            }
          }
        }
      }
    </script>
  </body>
</html>
 

参考文章:http://blog.ncmem.com/wordpress/2023/10/22/%e5%8e%9f%e7%94%9fjs%e5%ae%9e%e7%8e%b0%e5%a4%a7%e6%96%87%e4%bb%b6%e5%88%86%e7%89%87/

欢迎入群一起讨论

 

 

posted on 2023-10-22 09:33  Xproer-松鼠  阅读(45)  评论(0编辑  收藏  举报