解决js 调取Minio下载接口返回值的问题

前端项目直接调用Minio的getObject接口获取文件字节流时,txt文件可一次返回,pdf、word等文件会返回多个字节流,导致下载框频现、文件内容不全。文中给出解决方案,定义数组接收字节流,在所有字节流返回完毕后进行拼装,再转blob实现下载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        前端项目中直接调取minio的getObject接口会遇到返回多个字节流的问题

        之前实现下载功能都是调取后端提供的接口,直接获取到某个文件的所有字节流,然后转blob,实现下载功能。

        这是第一次直接调取minio的下载接口,直接获取minio上存储文件的字节流,txt文件可以一次全部返回,但是pdf,word等类型文件,会返回多个文件流,导致点击一次下载按钮,却频频出现下载框,并且出现拿到的文件内容不全的情况。解决方案如下:

        

// 下载minio中的文件

function getMinioFile(bucketName, fileName, callback, sourceName) {

    var size = 0 //定义一个记录完整字节流长度的变量

    window.minioClient.getObject(bucketName, fileName, (err, data) => {

        if (err) {

            return Message('下载失败')

        } else {

            let arr = new Array()//定义一个数组,接收接口返回的所有字节流

            data.on('data', function (chunk) {

                if (chunk.length > 0) {//如果返回的字节流为空,则不往arr里添加

                    arr.push(chunk)//接收字节流

                    size += chunk.length//记录字节流长度

                }

            })

            data.on('end', function () {//end时,说明所有字节流返回完毕

                const u8arr = new Uint8Array(size);//定义一个存放字节流的数组,把数组需要的大小作为参数传进去

                let u8arrindex = 0;//定义一个记录字节流数组位置的下标

                // 此时的arr是二元数组,所以需要双层循环,把所有字节流拿出来,拼装到u8arr中

                for (let i = 0; i < arr.length; i++) {

                    for (let j = 0; j < arr[i].length; j++) {

                        u8arr[u8arrindex] = arr[i][j];

                        u8arrindex += 1;

                    }

                }

                // u8arr中已存放了所有字节流,再进行转blob等操作

                callback(u8arr, sourceName)

            })

        }

    })

}

### MinIO 返回 499 错误代码的原因分析 HTTP 状态码 `499` 表示客户端已关闭连接,通常发生在客户端在服务器响应之前终止了请求的情况。对于 MinIO 而言,这种错误可能由多种因素引起,包括但不限于以下几点: #### 数据传输超时 当处理大量数据(如超过 3000 条记录)时,如果 HTTP 请求的时间过长,可能会触发客户端的超时设置,从而导致客户端主动断开连接[^1]。 #### 客户端配置问题 某些情况下,客户端的应用程序或网络库可能存在默认的超时时间限制。一旦请求持续时间超出此限制,客户端会强制中断连接并返回 `499` 错误。 --- ### 解决方案 以下是针对上述原因提出的几种解决方案: #### 增加客户端超时时间 可以通过调整客户端应用程序中的超时参数来延长等待时间。例如,在 Python 中使用 `requests` 库发送请求时,可以显式指定更大的超时值: ```python import requests response = requests.get('http://your-minio-server', timeout=600) # 设置超时时间为 600 秒 ``` 通过增加超时时间,允许更长时间的数据传输完成,减少因超时引发的 `499` 错误。 #### 使用分片上传技术 对于大文件或大批量数据的操作,建议采用分片上传的方式。MinIO 支持 S3 的多部分上传功能,能够将大数据分割成多个较小的部分分别上传,最后再合并为完整的对象。这种方式不仅提高了效率,还降低了单次请求失败的风险。 实现分片上传的一个简单例子如下所示: ```python from minio import Minio client = Minio( "play.min.io", access_key="Q3AM3UQ867SPQQA43P2F", secret_key="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG" ) # 初始化分片上传 response = client._make_request( method='POST', bucket_name='my-bucket', object_name='largefile.zip', query_params={'uploads': ''} ) upload_id = response.data.decode() # 分片上传各部分 part_number = 1 for chunk in read_in_chunks(file_path): # 自定义函数读取文件片段 part_response = client.put_object( 'my-bucket', f'largefile.zip?partNumber={part_number}&uploadId={upload_id}', data=chunk, length=len(chunk), ) part_number += 1 # 合并分片 complete_parts = [...] # 构造已完成的分片列表 client.complete_multipart_upload( 'my-bucket', 'largefile.zip', upload_id, complete_parts ) ``` 利用分片上传可有效规避单一请求耗时过久的问题。 #### 确保服务稳定性 为了防止由于终端会话结束而导致的服务中断,推荐使用 `nohup` 或者 `systemd` 方式启动 MinIO 服务[^2]。这样即使操作员意外退出登录也不会影响 MinIO 正常运行。 具体命令如下: ```bash nohup minio server --address :9002 ./data > minio.log 2>&1 & ``` 以上措施有助于维持长期稳定的环境,间接减少了潜在的 `499` 类型异常发生几率。 --- ### 总结 综上所述,MinIO 出现 `499` 错误的主要原因是客户端提前结束了尚未完全接收回应的 HTTP 连接。对此类情况的有效应对策略包括适当延展客户侧设定的最大容忍时限、运用支持断点续传特性的协议以及保障后台进程持久化执行等方面的工作。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值