大文件的分片上传和断点上传

一、大文件的分片上传

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chunked File Upload</title>
</head>
<body>
    <input type="file" id="fileInput">
    <button onclick="uploadFile()">Upload</button>

    <script>
        const chunkSize = 1024 * 1024; // 每个分片大小为1MB
        let file;
        let chunks = [];

        document.getElementById('fileInput').addEventListener('change', function(event) {
            file = event.target.files[0];
        });

        function uploadFile() {
            if (!file) {
                console.error('Please select a file.');
                return;
            }

            let fileSize = file.size;
            let numberOfChunks = Math.ceil(fileSize / chunkSize);

            for (let i = 0; i < numberOfChunks; i++) {
                let start = i * chunkSize;
                let end = Math.min(fileSize, start + chunkSize);
                let chunk = file.slice(start, end);
                chunks.push(chunk);
            }

            // 模拟分片上传
            uploadChunks(chunks);
        }

        function uploadChunks(chunks) {
            let currentChunk = 0;

            function uploadNextChunk() {
                if (currentChunk < chunks.length) {
                    let formData = new FormData();
                    formData.append('chunk', chunks[currentChunk]);
                    formData.append('totalChunks', chunks.length);
                    formData.append('chunkIndex', currentChunk);

                    // 发送分片数据给后端进行处理
                    // 这里可以使用fetch或者其他Ajax库发送请求

                    currentChunk++;
                    // 模拟延迟,实际应用中需要根据网络情况设置合适的延迟
                    setTimeout(uploadNextChunk, 1000);
                } else {
                    console.log('File upload complete!');
                }
            }

            uploadNextChunk();
        }
    </script>
</body>
</html>

在这个示例中,首先通过<input type="file">元素让用户选择要上传的文件,然后在点击"Upload"按钮时触发uploadFile()函数,该函数会将文件按照指定大小切分成多个分片,并调用uploadChunks()函数模拟分片上传过程。

二、大文件分片上传结合断点上传

前端将文件分片并逐个上传到后端,同时后端需要保存已上传的分片信息,以便在中断后能够恢复上传。以下是一个简单的示例,展示如何实现大文件的分片上传和断点上传:

前端代码示例(使用Fetch API)
javascript 复制代码
const chunkSize = 1024 * 1024; // 每个分片大小为1MB
let file;
let chunks = [];

document.getElementById('fileInput').addEventListener('change', function(event) {
    file = event.target.files[0];
});

function uploadChunk(chunkData, totalChunks, chunkIndex) {
    const formData = new FormData();
    formData.append('chunk', chunkData);
    formData.append('totalChunks', totalChunks);
    formData.append('chunkIndex', chunkIndex);

    fetch('https://api.example.com/uploadChunk', {
        method: 'POST',
        body: formData
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json();
    })
    .then(data => {
        console.log('Chunk uploaded successfully:', data);
        if (chunkIndex < chunks.length - 1) {
            uploadNextChunk(chunkIndex + 1);
        } else {
            console.log('File upload complete!');
        }
    })
    .catch(error => {
        console.error('There was a problem with the upload operation: ', error);
    });
}

function uploadNextChunk(chunkIndex) {
    uploadChunk(chunks[chunkIndex], chunks.length, chunkIndex);
}

function uploadFile() {
    if (!file) {
        console.error('Please select a file.');
        return;
    }

    let fileSize = file.size;
    let numberOfChunks = Math.ceil(fileSize / chunkSize);

    for (let i = 0; i < numberOfChunks; i++) {
        let start = i * chunkSize;
        let end = Math.min(fileSize, start + chunkSize);
        let chunk = file.slice(start, end);
        chunks.push(chunk);
    }

    uploadNextChunk(0); // 开始上传第一个分片
}

在上述前端代码中,uploadFile()函数会将文件分片后逐个上传到后端,如果其中某个分片上传失败,可以通过保存当前上传进度信息,再次发起上传请求来实现断点续传。

后端处理示例(基于Node.js和Express)
javascript 复制代码
const express = require('express');
const multer = require('multer');
const fs = require('fs');

const app = express();
const upload = multer({ dest: 'uploads/' });

app.post('/uploadChunk', upload.single('chunk'), (req, res) => {
    const chunk = req.file;
    const totalChunks = parseInt(req.body.totalChunks);
    const chunkIndex = parseInt(req.body.chunkIndex);

    // 保存分片文件
    fs.rename(chunk.path, `uploads/chunk_${chunkIndex}`, err => {
        if (err) {
            console.error(err);
            res.status(500).json({ message: 'Error saving chunk' });
        } else {
            res.json({ message: 'Chunk uploaded successfully' });
        }
    });
});

app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

以上是一个简单的示例代码,用于演示在前端实现大文件的分片上传和断点上传功能。在实际项目中,需要根据具体需求和后端服务的不同进行适当调整和扩展。

相关推荐
vim怎么退出19 分钟前
Dive into React——Diff 算法
前端·react.js·源码阅读
半个落月20 分钟前
面试必问的 JS 原型链,我用 16 个示例给你彻底讲明白
javascript
拾年27521 分钟前
别调 BERT 了:我用 Prompt 做了套 NLP 系统,20 分钟搞定
前端·人工智能
丷丩37 分钟前
12. 渲染:MapLibre GL JS 集成与多源瓦片联动
javascript·矢量瓦片·maplibre gl js·地图服务器
半个落月42 分钟前
别再死记变量提升了——从 V8 编译过程真正理解 JS 执行机制
前端
橘子星1 小时前
别再懵圈!JS 执行机制的 “千层套路” 全揭秘
前端·javascript
GuWenyue1 小时前
LeetCode 76 最小覆盖子串|JS 滑动窗口标准解法
前端·算法·面试
YHHLAI1 小时前
前端 HTTP 请求 & LLM 接口开发
前端·网络协议·http
拾年2751 小时前
__proto__ vs prototype:90% 的人分不清的 JavaScript 核心
前端·javascript·面试
国科安芯1 小时前
国科安芯推出商业航天级抗辐照半双工 RS485 收发器 ASC485S2Y
前端·单片机·嵌入式硬件·架构·安全性测试