大文件上传的方式

大文件上传通常需要分片处理、断点续传等技术来提高上传效率和可靠性。以下是一个简单的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记录已上传的分片索引,下次上传时跳过已上传的部分。
  • 并发控制:可以进一步优化,限制同时上传的分片数量,避免浏览器内存溢出。
相关推荐
李剑一5 分钟前
为什么几乎所有的知名开源项目都是外国人写的?
前端·ai编程·deepseek
小郎君6585 分钟前
(一)为什么表单需要第三种状态:disabled、readonly 与纯文本展示
前端·vue.js
计算机魔术师10 分钟前
1.4万亿没人接,OpenAI自己砍了1500亿
前端
程序员大阳22 分钟前
副队长JavaScript教程(56)-DOM之表单操作
javascript·dom·表单操作
Dxy12393102161 小时前
JS AES加密详解
开发语言·javascript·ecmascript
溪语流沙1 小时前
【每天一个CSS | Day41】开关三连:一套状态机,三种视觉翻译
前端·css·html5·每日一练·按钮
变与不变8061 小时前
css定位布局精讲
前端·css
香蕉大香蕉(06敬畏市场)1 小时前
MySQL 单点详解(03)
java·数据库·mysql·面试·八股·大厂实习
FRing032 小时前
JavaScript入门到精通三十三(异常处理、call方法、apply方法、bind方法、防抖、节流)
开发语言·前端·javascript
计算机魔术师2 小时前
OpenAI 砍掉 100 亿融资目标,AI 资本市场的温度计变了
前端