javascript原生+django实现文件断点上传

html代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 引入spark-MD5.js计算文件MD5值 -->
    <script src="https://cdn.bootcss.com/spark-md5/3.0.0/spark-md5.js" type="text/javascript"></script>
    <title>Document</title>
</head>
<body>
    <input type="file" name="file">
    <script>
        // 设置每次断点上传的文件大小
        const SIZE = 10 * 1024 * 1024;
        // 文件断点分片方法
        function getChunk(file) {
            const fileChunkList = [];
            let i = 0;
            while (i < file.size) {
                fileChunkList.push({ file: file.slice(i, i + SIZE) });
                i += SIZE;
            }
            return fileChunkList;
        }
        // 发起文件分片上传请求
        function upload(data) {
            return new Promise(resolve => {
                const xhr = new XMLHttpRequest()
                xhr.open('POST', "http://127.0.0.1:8000/file/")
                xhr.send(data)
                xhr.onreadystatechange = (e) => {
                    if (xhr.readyState === 4) {
                        if (xhr.status >= 200 && xhr.status <= 300) {
                            resolve({
                                result: JSON.parse(xhr.responseText)
                            })
                        } else if (xhr.status >= 400) {
                            resolve({
                                result: xhr.status
                            })
                        }
                    }
                }
            })
        }
        // 文件分片上传完毕执行文件合并代码
        function merge(data) {
            const xhr = new XMLHttpRequest()
            xhr.open('POST', "http://127.0.0.1:8000/merge/")
            xhr.send(data)
            xhr.onreadystatechange = (e) => {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status <= 300) {
                        console.log(JSON.parse(xhr.responseText));
                    } else if (xhr.status >= 400) {
                        console.log(xhr.status);
                    }
                }
            }
        }
        // 获取input对象
        const input = document.querySelector("input")
        // 监听文件变化
        input.addEventListener("change", function (e) {
            let file = e.target.files[0]
            // 接下来为了获取文件md5
            const fileReader = new FileReader()
            fileReader.readAsBinaryString(file);
            fileReader.onload = async e => {
                const md5 = SparkMD5.hashBinary(e.target.result);
                const chunkList = getChunk(file)
                const formDataList = chunkList.map(async (item, index) => {
                    const formData = new FormData()
                    formData.append("chunk", item.file)
                    formData.append("index", index)
                    formData.append("md5", md5)
                    formData.append("name", file.name)
                    await upload(formData)
                    console.log("分块执行时间" + new Date().getTime());
                })
                Promise.all(formDataList).then(e => {
                    console.log("合并执行时间" + new Date().getTime());
                    const mergeData = new FormData()
                    mergeData.append("md5", md5)
                    mergeData.append("name", file.name)
                    mergeData.append("index", formDataList.length)
                    merge(mergeData)
                })
            }
        })
    </script>
</body>

</html>

python

def merge(request):
    md5 = request.POST.get("md5")
    name = request.POST.get("name")
    index = request.POST.get("index")
    print(index)
    file_name = f"{md5}-{name}"
    print(file_name)
    print(f"文件合并{time.time()}")
    temp_file = open(f"./static/{file_name}", 'wb+')
    for i in range(0, int(index)):
        with open(f"./static/{file_name}-{i}", "rb+") as f:
            temp_file.write(f.read())
    temp_file.close()
    return JsonResponse({'code': 200, 'msg': '文件合并成功'})


def file(request):
    index = request.POST.get("index")
    md5 = request.POST.get("md5")
    name = request.POST.get("name")
    file_name = f"{md5}-{name}-{index}"
    if os.path.exists("./static/" + file_name):
        return JsonResponse({'code': 200, 'msg': '上传成功'})
    with open("./static/" + file_name, "wb+") as destination:
        for chunk in request.FILES["chunk"].chunks():
            destination.write(chunk)
    print(f"文件上传{time.time()}")
    return JsonResponse({'code': 200, 'msg': '上传成功'})

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值