web-dev-qa-db-ja.com

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出力をコンソールに取得してWebブラウザーに貼り付けると、必要なファイルがダウンロードされます。

ただし、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の1つにブレークポイントを置くと、IDE(NetBeans)はエラーをスローし、データの値を表示することを拒否します。これは単なるIDEですが、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に到達しないことが示されます。

何が間違っていますか?

53
Sara Tibbetts

S3 APIからgetObject()を実行すると、 docs ごとに、ファイルの内容は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オブジェクトから新しいバッファーを作成する必要はないかもしれませんが、必要な場合は上記のサンプルを使用してそれを実現できます。

95
peteb

@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(...);
13
Arian Acosta

あるいは、 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)
  })
})

免責事項:私は Minio のために働いています。そのオープンソース、golangで書かれたS3互換のオブジェクトストレージ JavaPythonJsgolang

2
koolhead17

一見、何か悪いことをしているようには見えませんが、すべてのコードを表示しているわけではありません。私が最初にS3と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());
        });
    }
});
1
bknights