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

AWS SDK v3 JavaScript GetObjectCommand未返回预期PDF二进制内容

解决AWS SDK v3获取S3文件二进制内容的问题

问题原因

在AWS SDK for JavaScript v3中,GetObjectCommand返回的response.Body是Node.js可读流(IncomingMessage),而非直接的二进制数据,所以直接await response.Body无法得到预期内容。

解决方案

需要将可读流转换为Buffer(二进制内容),以下是几种可行实现方式:

方法1:使用stream.promises的pipeline(推荐)

利用Node.js内置模块处理流,自带错误处理,代码更简洁:

const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
const { pipeline } = require('stream/promises');
const { Writable } = require('stream');

let client = new S3Client({
    region: 'xxxxx',
    credentials: {
        accessKeyId: 'xxxxx',
        secretAccessKey: 'xxxxx'
    }
});

const getObjectFromS3 = async (pdfFileName) => {
    const command = new GetObjectCommand({
        Bucket: "xxxxxxx",
        Key: pdfFileName,
    });
    const response = await client.send(command);
    
    // 将可读流转换为Buffer
    const chunks = [];
    await pipeline(
        response.Body,
        new Writable({
            write(chunk, _, callback) {
                chunks.push(chunk);
                callback();
            }
        })
    );
    const content = Buffer.concat(chunks);
    console.log(content); // 此时为PDF的二进制Buffer
    return content;
};

方法2:手动监听流事件

通过监听流的data/end/error事件收集数据块,最终合并为Buffer:

const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");

let client = new S3Client({
    region: 'xxxxx',
    credentials: {
        accessKeyId: 'xxxxx',
        secretAccessKey: 'xxxxx'
    }
});

const streamToBuffer = (stream) => {
    return new Promise((resolve, reject) => {
        const chunks = [];
        stream.on('data', (chunk) => chunks.push(chunk));
        stream.on('end', () => resolve(Buffer.concat(chunks)));
        stream.on('error', reject);
    });
};

const getObjectFromS3 = async (pdfFileName) => {
    const command = new GetObjectCommand({
        Bucket: "xxxxxxx",
        Key: pdfFileName,
    });
    const response = await client.send(command);
    const content = await streamToBuffer(response.Body);
    console.log(content);
    return content;
};

方法3:兼容旧版Node.js的实现

如果Node.js版本低于15.x,用util.promisify包装传统stream.pipeline:

const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
const { pipeline } = require('stream');
const { promisify } = require('util');
const pipelineAsync = promisify(pipeline);

let client = new S3Client({
    region: 'xxxxx',
    credentials: {
        accessKeyId: 'xxxxx',
        secretAccessKey: 'xxxxx'
    }
});

const getObjectFromS3 = async (pdfFileName) => {
    const command = new GetObjectCommand({
        Bucket: "xxxxxxx",
        Key: pdfFileName,
    });
    const response = await client.send(command);
    
    const chunks = [];
    await pipelineAsync(
        response.Body,
        (source) => {
            source.on('data', (chunk) => chunks.push(chunk));
            return source;
        }
    );
    const content = Buffer.concat(chunks);
    console.log(content);
    return content;
};

验证方式

转换后的content是Buffer类型,可通过以下方式验证:

const fs = require('fs/promises');
await fs.writeFile('local.pdf', content);

打开生成的local.pdf,若能正常显示则转换成功。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:30:10