前端大文件上传/分片上传

前置知识

  1. File对象:表示一组文件,我们使用<input type="file" /> 去选择文件时,这些文件就被存储在File对象中。

  2. Blob对象:表示二进制数据,常用于存储大型数据对象(如图像、音频等)。File对象是Blob对象的一个子类,它继承了Blob对象的所有属性和方法。

  3. formData对象:前端先将文件存储在formData当中,才能传输给后端。

  1. 设置chunksize
  2. 调用Slice切割blob对象,获得一个个小chunk
  3. 将这些chunk添加到formData当中
  4. 将formData传输给后端
    大文件上传 核心就是 File.Slice()方法,对文件进行切割,将大文件切割成一个个小文件,然后交给后端

点击查看代码
<!DOCTYPE html>
<html lang="en">

<body>
    <div class="container">
        <h1>大文件上传</h1>
        <input type="file" id="fileInput" accept="image/*">

        <button id="uploadButton">切片上传</button>

        <button id="sliceButton">文件切片</button>
        <img id="sliceImg" alt="">
        <br>
    </div>
    <script>
        document.getElementById('sliceButton').addEventListener('click', function () {
            const fileInput = document.getElementById('fileInput')
            const file = fileInput.files[0] // 获取file对象
            const imgElement = document.getElementById('sliceImg')

            const sliceBlob = file.slice(0, 10 * 1024, file.type)
            //sliceBlob就是一个切片,也就是小文件(上面这里是起始到100KB的意思)
            const reader = new FileReader()
            reader.onload = function (e) {
                imgElement.src = e.target.result
                imgElement.style.display = 'block'
            }
            reader.readAsDataURL(sliceBlob)


        })



        //chunk就是一个切片,也就是小文件
        async function uploadChunk (chunk) {
            const formData = new FormData()
            formData.append('fileName', 'test.jpg')
            formData.append('file', chunk)

            //这里的地址可以替换为你的后端地址
            const response = await fetch('https://file.io', {
                method: 'POST',
                body: formData
            })

            const result = await response.json()
            return result
        }

        document.getElementById('uploadButton').addEventListener('click', async function () {
            const fileInput = document.getElementById('fileInput')
            const file = fileInput.files[0]
            const chunkSize = 10 * 1024 // 10KB
            const totalChunks = Math.ceil(file.size / chunkSize)

            for (let i = 0; i < totalChunks; i++) {
                const start = i * chunkSize  // 代表此块切片的起始字节
                const end = Math.min(start + chunkSize, file.size) // 代表此块切片的终止字节
                const chunk = file.slice(start, end)
                //上传一个切片
                console.log(`正在上传第${i + 1}个切片`)
                console.log({ chunk })
                const result = await uploadChunk(chunk)

            }
        });
    </script>
</body>

</html>

踩坑:

这样获取出来的files是一个fileList,需要手动取出第0个,才是具体的file对象

var input = document.getElementById("fileInput")
var files = input.files

参考:https://blog.csdn.net/wtswts1232/article/details/130663725

posted @ 2024-07-08 20:22  卡优卡1255  阅读(43)  评论(0)    收藏  举报