大文件上传的方式

大文件上传通常需要分片处理、断点续传等技术来提高上传效率和可靠性。以下是一个简单的JavaScript示例,展示如何实现大文件的分片上传和断点续传:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>大文件上传</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.24.0/axios.min.js"></script>
</head>
<body>
    <input type="file" id="fileInput" />
    <button id="uploadBtn">上传</button>
    <progress id="progressBar" value="0" max="100"></progress>

    <script>
        // 请求基准地址
        axios.defaults.baseURL = 'http://localhost:3000';

        // 选中的文件
        var file = null;

        // 选择文件
        document.getElementById('fileInput').onchange = function(event) {
            file = event.target.files[0];
        };

        // 开始上传
        document.getElementById('uploadBtn').onclick = async function() {
            if (!file) return;

            const chunkSize = 10 * 1024 * 1024; // 10MB 切片大小
            const chunks = fileToChunks(file, chunkSize);
            const chunkHashes = await getChunksHashes(chunks);
            const uploadedChunks = new Set(JSON.parse(localStorage.getItem(file.name)) || []);

            for (let i = 0; i < chunks.length; i++) {
                if (uploadedChunks.has(i)) {
                    console.log(`Chunk ${i} 已经上传`);
                    continue;
                }

                const formData = new FormData();
                formData.append('chunk', chunks[i]);
                formData.append('hash', chunkHashes[i]);
                formData.append('index', i);
                formData.append('filename', file.name);

                try {
                    const response = await axios.post('/upload', formData);
                    console.log(`Chunk ${i} 上传成功`);
                    uploadedChunks.add(i);
                } catch (error) {
                    console.error(`Chunk ${i} 上传失败`, error);
                }
            }

            await axios.get('/merge', { params: { filename: file.name } });
            console.log('上传完成');
        };

        function fileToChunks(file, size) {
            const chunks = [];
            for (let start = 0; start < file.size; start += size) {
                const chunk = file.slice(start, start + size);
                chunks.push({ hash: Date.now(), chunk: chunk });
            }
            return chunks;
        }

        async function getChunksHashes(chunks) {
            const hashes = [];
            for (const chunk of chunks) {
                const hash = await new Promise((resolve) => {
                    const reader = new FileReader();
                    reader.onload = (event) => {
                        resolve(spark.end(event.target.result));
                    };
                    reader.readAsArrayBuffer(chunk.chunk);
                });
                hashes.push(hash);
            }
            return hashes;
        }
    </script>
</body>
</html>

代码解析:

  1. 文件选择与切片

    • 用户选择文件后,代码将文件分片,每个分片大小为10MB。
    • fileToChunks函数负责将文件分割成多个分片,并为每个分片生成一个唯一的哈希值。
  2. 上传分片

    • 使用axios库将每个分片上传到服务器。
    • 每个分片上传成功后,将分片索引记录到localStorage中,以便断点续传。
  3. 合并分片

    • 所有分片上传完成后,通过GET请求通知服务器合并分片。
  4. 进度展示

    • 使用<progress>元素实时展示上传进度。

进阶功能:

  • 断点续传 :通过localStorage记录已上传的分片索引,下次上传时跳过已上传的部分。
  • 并发控制:可以进一步优化,限制同时上传的分片数量,避免浏览器内存溢出。
相关推荐
lbh2 小时前
当我开始像写代码一样和AI对话,一切都变了
前端·openai·ai编程
We་ct2 小时前
LeetCode 918. 环形子数组的最大和:两种解法详解
前端·数据结构·算法·leetcode·typescript·动态规划·取反
qq_406176143 小时前
深入浅出 Pinia:Vue3 时代的状态管理新选择
javascript·vue.js·ecmascript
wefly20173 小时前
m3u8live.cn 在线M3U8播放器,免安装高效验流排错
前端·后端·python·音视频·前端开发工具
C澒3 小时前
微前端容器标准化 —— 公共能力篇:通用打印
前端·架构
德育处主任Pro4 小时前
前端元素转图片,dom-to-image-more入门教程
前端·javascript·vue.js
木斯佳4 小时前
前端八股文面经大全:小红书前端一二面OC(下)·(2026-03-17)·面经深度解析
前端·vue3·proxy·八股·响应式
陈天伟教授4 小时前
人工智能应用- 预测新冠病毒传染性:04. 中国:强力措施遏制疫情
前端·人工智能·安全·xss·csrf
叫我一声阿雷吧4 小时前
JS 入门通关手册(23):JS 异步编程:回调函数与异步本质
javascript·es6·前端面试·回调函数·回调地狱·js异步编程·异步本质
zayzy4 小时前
前端八股总结
开发语言·前端·javascript