You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中MinIO Client流转JSON异常:仅返回首项或空数组

问题:Next.js中MinIO listObjectsV2返回数据异常的排查与修复

我尝试在Next.js中创建REST API接口,通过MinIO Client的listObjectsV2方法获取存储桶内的对象列表并返回完整JSON,但遇到问题:直接将流数据传入resolve时,仅能得到第一个对象;尝试将对象转为数组返回时,却得到空数组[]。以下是我的两段测试代码及对应的控制台日志:

第一段代码(直接返回流)

export async function GET() {
    return new Promise(resolve => {
        const objectsStream = s3Client.listObjectsV2('node', '', true, '')
        objectsStream.on('data', function (obj) {
            console.log(obj)
            resolve(NextResponse.json((obj)))
        })
        /* Error Hand */
        objectsStream.on('error', function (e) {
            resolve(NextResponse.json(e))
        })
    })
}

控制台日志

{
  name: '00002.png',
  lastModified: 2023-12-28T15:44:26.762Z,
  etag: 'f1684b805ec19d1cd993a50173acb64b',
  size: 13664646
}
{
  name: '00040.png',
  lastModified: 2023-12-28T15:44:39.300Z,
  etag: '23efca60e3ca26165f1bb12a9e19d223',
  size: 5197315
}

返回结果

仅返回第一个对象:

{
  "name": "00002.png",
  "lastModified": "2023-12-28T15:44:26.762Z",
  "etag": "f1684b805ec19d1cd993a50173acb64b",
  "size": 13664646
}

第二段代码(转为数组返回)

export async function GET() {
    return new Promise(resolve => {
        const objectsStream = s3Client.listObjectsV2('node', '', true, '')
        objectsStream.on('data', function (obj) {
            const arr = Object.assign([], obj);
            console.log(arr)
            resolve(NextResponse.json((JSON.stringify(arr))))
        })
        objectsStream.on('error', function (e) {
            resolve(NextResponse.json(e))
        })
    })
}

控制台日志

[
  name: '00002.png',
  lastModified: 2023-12-28T15:44:26.762Z,
  etag: 'f1684b805ec19d1cd993a50173acb64b',
  size: 13664646
]
[
  name: '00040.png',
  lastModified: 2023-12-28T15:44:39.300Z,
  etag: '23efca60e3ca26165f1bb12a9e19d223',
  size: 5197315
]

返回结果

返回空数组:[]


错误原因分析

第一段代码的问题

  • Promise的resolve()只能执行一次,第一次data事件触发时就调用了resolve,后续的对象数据根本没有机会被处理,所以只返回第一个对象。
  • listObjectsV2返回的是流,data事件会分批触发,每一次事件传递一个对象,不能在单次data事件里直接结束Promise。

第二段代码的问题

  • Object.assign([], obj)是把对象的属性复制到数组中,但对象的键(如name、lastModified)不是数组的数字索引,JSON序列化时会忽略这些非数字索引的属性,所以最终得到空数组。
  • 同样犯了在单次data事件里调用resolve的错误,只处理了第一个对象,没有收集所有数据。

修复后的代码

export async function GET() {
  return new Promise((resolve, reject) => {
    const objectsStream = s3Client.listObjectsV2('node', '', true, '');
    const objectsList = [];

    // 收集每一个返回的对象
    objectsStream.on('data', (obj) => {
      objectsList.push(obj);
      console.log(obj);
    });

    // 流结束时,返回完整的对象列表
    objectsStream.on('end', () => {
      resolve(NextResponse.json(objectsList));
    });

    // 错误处理:用reject抛出异常,同时设置500状态码
    objectsStream.on('error', (e) => {
      reject(NextResponse.json(e, { status: 500 }));
    });
  });
}

修复说明

  • 初始化空数组objectsList,在每一次data事件触发时,将对象推入数组,完成所有数据的收集。
  • 监听流的end事件,当所有数据接收完毕后,再调用resolve返回完整的对象列表JSON。
  • 错误处理改用reject,符合Promise的规范,同时返回500状态码明确标识服务器错误。

内容的提问来源于stack exchange,提问作者Load Galax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 10:17:35