前端大文件分片上传到 MinIO

在现代Web应用中,用户经常需要上传大文件,如视频、图片等。由于浏览器限制和网络带宽的原因,直接上传大文件可能导致上传失败或者体验不佳。为了提升用户体验,可以采用分片上传的方式。分片上传是将一个大文件分割成多个小文件(片),逐个上传到服务器,上传完成后再进行合并。本文将介绍如何使用前端技术将大文件分片上传到 MinIO。

什么是 MinIO?

MinIO 是一个高性能的对象存储服务,兼容 Amazon S3 API,支持大文件的存储和快速访问。在 MinIO 中,文件以对象的形式存储,适合用于处理海量数据存储。

分片上传的流程

  1. 文件选择:用户选择需要上传的文件。
  2. 文件分片:将大文件切分为若干个小片。
  3. 分片上传:逐个上传这些片到 MinIO。
  4. 合并分片:所有片上传完毕后,可以在服务器端将这些片合并成一个完整的文件。

前端代码示例

下面是一个使用 JavaScript 和 HTML 实现分片上传到 MinIO 的基本示例:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MinIO 分片上传示例</title>
</head>
<body>
    <input type="file" id="fileInput" />
    <button id="uploadBtn">上传</button>
    <script>
        const chunkSize = 5 * 1024 * 1024; // 每个片的大小为5MB
        const endpoint = 'http://minio-server:9000'; // 替换为你的 MinIO 地址
        const accessKey = 'your-access-key'; // MinIO Access Key
        const secretKey = 'your-secret-key'; // MinIO Secret Key

        document.getElementById('uploadBtn').addEventListener('click', async () => {
            const fileInput = document.getElementById('fileInput');
            const file = fileInput.files[0];
            if (!file) {
                alert('请先选择文件');
                return;
            }

            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);
                await uploadChunk(chunk, file.name, i, totalChunks);
            }
            alert('所有片上传完成');
        });

        async function uploadChunk(chunk, filename, chunkIndex, totalChunks) {
            const url = `${endpoint}/${filename}.part${chunkIndex}`;
            const response = await fetch(url, {
                method: 'PUT',
                headers: {
                    'Authorization': 'Bearer ' + btoa(`${accessKey}:${secretKey}`),
                    'Content-Type': 'application/octet-stream'
                },
                body: chunk
            });

            if (response.ok) {
                console.log(`第${chunkIndex + 1}/${totalChunks}片上传成功`);
            } else {
                console.error(`第${chunkIndex + 1}/${totalChunks}片上传失败`);
            }
        }
    </script>
</body>
</html>

解释代码

  1. 文件选择:用户通过 <input type="file"> 标签选择文件。
  2. 分片计算:利用 slice 方法将文件切割成多个片,每个片的大小由 chunkSize 控制。
  3. 分片上传:利用 fetch API 将每个片上传到 MinIO。上传的 URL 为 http://minio-server:9000/{filename}.part{chunkIndex}
  4. 基础认证:这里使用了简单的 Basic Auth 进行认证,以 Authorization 头部携带 AccessKey 和 SecretKey。

注意事项

  • 确保 MinIO 服务已经启动并可访问。
  • 根据需要配置 CORS 策略,允许前端请求。
  • 上传成功后,后端需要实现相应的合并逻辑,将上传的片合并成完整文件。
  • 可以考虑使用 Promise.all 并发上传片以提高效率。

通过这种方式,我们可以确保大文件的可靠上传,提高用户体验以及上传成功率。希望这个示例能够对你在前端大文件上传的实现有所帮助。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部