javascript - node - s3 copy object




Como obter resposta do getObject S3 no Node.js? (3)

Em um projeto do Node.js, estou tentando recuperar dados do S3.

Quando eu uso getSignedURL , tudo funciona:

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

Meus params são:

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

Se eu pegar a saída da URL para o console e colá-la em um navegador da Web, ela fará o download do arquivo de que preciso.

No entanto, se eu tentar usar getObject , obtenho todos os tipos de comportamentos estranhos. Eu acredito que estou apenas usando isso incorretamente. Isso é o que eu tentei:

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

Saídas:

{ 
  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

Então parece que isso está funcionando corretamente. No entanto, quando eu coloco um ponto de interrupção em um dos console.log s, meu IDE (NetBeans) lança um erro e se recusa a mostrar o valor dos dados. Enquanto isso poderia ser apenas o IDE, decidi tentar outras maneiras de usar o getObject .

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

Isso não produz nada. Colocar um ponto de interrupção em mostra que o código nunca atinge qualquer um dos console.log s. Eu também tentei:

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

No entanto, isso também não produz nada e colocar um ponto de interrupção mostra que o console.log nunca é alcançado.

O que estou fazendo de errado?


À primeira vista, não parece que você está fazendo nada errado, mas você não mostra todo o seu código. O seguinte funcionou para mim quando eu estava primeiro verificando S3 e 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());
        });
    }
});

Alternativamente, você pode usar a biblioteca do cliente 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: Eu trabalho para Minio Seu open source, armazenamento de objeto compatível com S3 escrito em golang com bibliotecas cliente disponíveis em Java , Python , Js , golang .


Baseado na resposta de @peteb, mas usando Promises e 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(...);




amazon-s3