IT TIP

Node.js의 S3 getObject에서 응답을 얻는 방법은 무엇입니까?

itqueen 2020. 12. 10. 21:36
반응형

Node.js의 S3 getObject에서 응답을 얻는 방법은 무엇입니까?


Node.js 프로젝트에서 S3에서 데이터를 가져 오려고합니다.

을 사용 getSignedURL하면 모든 것이 작동합니다.

aws.getSignedUrl('getObject', params, function(err, url){
    console.log(url); 
}); 

내 매개 변수는 다음과 같습니다.

var params = {
              Bucket: "test-aws-imagery", 
              Key: "TILES/Level4/A3_B3_C2/A5_B67_C59_Tiles.par"

URL 출력을 콘솔로 가져 와서 웹 브라우저에 붙여 넣으면 필요한 파일이 다운로드됩니다.

그러나 사용하려고 getObject하면 모든 종류의 이상한 행동이 나타납니다. 나는 그것을 잘못 사용하고 있다고 생각합니다. 이것이 내가 시도한 것입니다.

aws.getObject(params, function(err, data){
    console.log(data); 
    console.log(err); 
}); 

출력 :

{ 
  AcceptRanges: 'bytes',
  LastModified: 'Wed, 06 Apr 2016 20:04:02 GMT',
  ContentLength: '1602862',
  ETag: '9826l1e5725fbd52l88ge3f5v0c123a4"',
  ContentType: 'application/octet-stream',
  Metadata: {},
  Body: <Buffer 01 00 00 00  ... > }

  null

그래서 이것이 제대로 작동하는 것 같습니다. 그러나 console.logs 중 하나에 중단 점을 설정하면 IDE (NetBeans)에서 오류가 발생하고 데이터 값 표시를 거부합니다. 이것이 단지 IDE 일 수 있지만 .NET을 사용하는 다른 방법을 시도하기로 결정했습니다 getObject.

aws.getObject(params).on('httpData', function(chunk){
    console.log(chunk); 
}).on('httpDone', function(data){
    console.log(data); 
});

이것은 아무것도 출력하지 않습니다. 중단 점을 넣으면 코드가 console.logs에 도달하지 않는다는 것을 보여줍니다 . 나는 또한 시도했다 :

aws.getObject(params).on('success', function(data){
    console.log(data); 
});

그러나 이것은 또한 아무것도 출력하지 않으며 중단 점을 배치하면에 console.log도달하지 않음을 보여줍니다 .

내가 도대체 ​​뭘 잘못하고있는 겁니까?


getObject()S3 API에서를 수행 할 때 문서 별로 파일의 내용이 Body속성에 있으며 샘플 출력에서 ​​볼 수 있습니다. 다음과 같은 코드가 있어야합니다.

const aws = require('aws-sdk');
const s3 = new aws.S3(); // Pass in opts to S3 if necessary

var getParams = {
    Bucket: 'abc', // your bucket name,
    Key: 'abc.txt' // path to the object you're looking for
}

s3.getObject(getParams, function(err, data) {
    // Handle any error and exit
    if (err)
        return err;

  // No error happened
  // Convert Body from a Buffer to a String

  let objectData = data.Body.toString('utf-8'); // Use the encoding necessary
});

data.Body객체 에서 새 버퍼를 만들 필요는 없지만 필요한 경우 위의 샘플을 사용하여이를 수행 할 수 있습니다.


@peteb의 답변을 기반으로하지만 Promises사용 Async/Await:

const AWS = require('aws-sdk');

const s3 = new AWS.S3();

async function getObject (bucket, objectKey) {
  try {
    const params = {
      Bucket: bucket,
      Key: objectKey 
    }

    const data = await s3.getObject(params).promise();

    return data.Body.toString('utf-8');
  } catch (e) {
    throw new Error(`Could not retrieve file from S3: ${e.message}`)
  }
}

// To retrieve you need to use `await getObject()` or `getObject().then()`
getObject('my-bucket', 'path/to/the/object.txt').then(...);

또는 minio-js 클라이언트 라이브러리 get-object.js를 사용할 수 있습니다.

var Minio = require('minio')

var s3Client = new Minio({
  endPoint: 's3.amazonaws.com',
  accessKey: 'YOUR-ACCESSKEYID',
  secretKey: 'YOUR-SECRETACCESSKEY'
})

var size = 0
// Get a full object.
s3Client.getObject('my-bucketname', 'my-objectname', function(e, dataStream) {
  if (e) {
    return console.log(e)
  }
  dataStream.on('data', function(chunk) {
    size += chunk.length
  })
  dataStream.on('end', function() {
    console.log("End. Total size = " + size)
  })
  dataStream.on('error', function(e) {
    console.log(e)
  })
})

Disclaimer: I work for Minio Its open source, S3 compatible object storage written in golang with client libraries available in Java, Python, Js, golang.


At first glance it doesn't look like you are doing anything wrong but you don't show all your code. The following worked for me when I was first checking out S3 and Node:

var AWS = require('aws-sdk');

if (typeof process.env.API_KEY == 'undefined') {
    var config = require('./config.json');
    for (var key in config) {
        if (config.hasOwnProperty(key)) process.env[key] = config[key];
    }
}

var s3 = new AWS.S3({accessKeyId: process.env.AWS_ID, secretAccessKey:process.env.AWS_KEY});
var objectPath = process.env.AWS_S3_FOLDER +'/test.xml';
s3.putObject({
    Bucket: process.env.AWS_S3_BUCKET, 
    Key: objectPath,
    Body: "<rss><data>hello Fred</data></rss>",
    ACL:'public-read'
}, function(err, data){
    if (err) console.log(err, err.stack); // an error occurred
    else {
        console.log(data);           // successful response
        s3.getObject({
            Bucket: process.env.AWS_S3_BUCKET, 
            Key: objectPath
        }, function(err, data){
            console.log(data.Body.toString());
        });
    }
});

For someone looking for a NEST JS TYPESCRIPT version of the above:

    /**
     * to fetch a signed URL of a file
     * @param key key of the file to be fetched
     * @param bucket name of the bucket containing the file
     */
    public getFileUrl(key: string, bucket?: string): Promise<string> {
        var scopeBucket: string = bucket ? bucket : this.defaultBucket;
        var params: any = {
            Bucket: scopeBucket,
            Key: key,
            Expires: signatureTimeout  // const value: 30
        };
        return this.account.getSignedUrlPromise(getSignedUrlObject, params);
    }

    /**
     * to get the downloadable file buffer of the file
     * @param key key of the file to be fetched
     * @param bucket name of the bucket containing the file
     */
    public async getFileBuffer(key: string, bucket?: string): Promise<Buffer> {
        var scopeBucket: string = bucket ? bucket : this.defaultBucket;
        var params: GetObjectRequest = {
            Bucket: scopeBucket,
            Key: key
        };
        var fileObject: GetObjectOutput = await this.account.getObject(params).promise();
        return Buffer.from(fileObject.Body.toString());
    }

    /**
     * to upload a file stream onto AWS S3
     * @param stream file buffer to be uploaded
     * @param key key of the file to be uploaded
     * @param bucket name of the bucket 
     */
    public async saveFile(file: Buffer, key: string, bucket?: string): Promise<any> {
        var scopeBucket: string = bucket ? bucket : this.defaultBucket;
        var params: any = {
            Body: file,
            Bucket: scopeBucket,
            Key: key,
            ACL: 'private'
        };
        var uploaded: any = await this.account.upload(params).promise();
        if (uploaded && uploaded.Location && uploaded.Bucket === scopeBucket && uploaded.Key === key)
            return uploaded;
        else {
            throw new HttpException("Error occurred while uploading a file stream", HttpStatus.BAD_REQUEST);
        }
    }

참고URL : https://stackoverflow.com/questions/36942442/how-to-get-response-from-s3-getobject-in-node-js

반응형