[解決済み] 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.log
は、私のIDE(NetBeans)がエラーを投げ、データの値を表示することを拒否します。これはIDEだけの問題かもしれませんが、私は他の方法を試してみることにしました。
getObject
.
aws.getObject(params).on('httpData', function(chunk){
console.log(chunk);
}).on('httpDone', function(data){
console.log(data);
});
これでは何も出力されません。 ブレークポイントを置くと、コードは決して
console.log
s. も試してみました。
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
オブジェクトがありますが、必要であれば、上記のサンプルを使って実現できます。
aws-sdk/client-s3 (2021年版)
2016年にこの回答を書いてから、Amazonは新しいJavaScript SDKをリリースしました。
@aws-sdk/client-s3
. この新しいバージョンは、オリジナルの
getObject()
によってオプトインする代わりに、常にプロミスを返すことによって
.promise()
に連鎖している。
getObject()
. それに加えて
response.Body
は、もはや
Buffer
の1つですが
Readable|ReadableStream|Blob
. これは
response.Data
を少し。これは、すべての内容をメモリに保持する代わりに、返されたデータをストリームすることができるので、よりパフォーマンスが高くなるはずです。トレードオフとして、実装が少し冗長になります。
以下の例では
response.Body
のデータは配列にストリーミングされ、文字列として返されます。これは、私の最初の答えに相当する例です。あるいは
response.Body
を使用することができます。
stream.Readable.pipe()
を HTTP レスポンスやファイル、その他あらゆるタイプの
stream.Writeable
を使用すると、大きなオブジェクトを取得する際に、よりパフォーマンスの高い方法となります。
を使いたい場合は
Buffer
のように、元の
getObject()
レスポンスで、これを行うには
responseDataChunks
の中に
Buffer.concat()
を使用する代わりに
Array#join()
これは、バイナリデータを扱うときに便利です。注意すべきは
Array#join()
は文字列を返すので、各
Buffer
のインスタンスは
responseDataChunks
を持つことになります。
Buffer.toString()
が暗黙のうちに呼び出され、デフォルトのエンコーディングである
utf8
が使用されます。
const { GetObjectCommand, S3Client } = require('@aws-sdk/client-s3')
const client = new S3Client() // Pass in opts to S3 if necessary
function getObject (Bucket, Key) {
return new Promise(async (resolve, reject) => {
const getObjectCommand = new GetObjectCommand({ Bucket, Key })
try {
const response = await client.send(getObjectCommand)
// Store all of data chunks returned from the response data stream
// into an array then use Array#join() to use the returned contents as a String
let responseDataChunks = []
// Handle an error while streaming the response body
response.Body.once('error', err => reject(err))
// Attach a 'data' listener to add the chunks of data to our array
// Each chunk is a Buffer instance
response.Body.on('data', chunk => responseDataChunks.push(chunk))
// Once the stream has no more data, join the chunks into a string and return the string
response.Body.once('end', () => resolve(responseDataChunks.join('')))
} catch (err) {
// Handle the error or throw
return reject(err)
}
})
}
@aws-sdk/client-s3
ドキュメントリンク
関連
-
[解決済み】Facebook Graph API のクエリで with=location を使用すると "Uncaught (in promise) undefined" というエラーが発生する。
-
[解決済み】Angular JS Uncaught Error。[インジェクター:モジュラー]。
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryで要素が非表示になっているかどうかを確認するには?
-
[解決済み] JavaScriptでタイムスタンプを取得する方法は?
-
[解決済み] Node.jsのプログラムにコマンドライン引数を渡すにはどうしたらいいですか?
-
[解決済み] Node.jsを使うタイミングをどう判断するか?
-
[解決済み] Node.jsで終了する方法
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Heroku:ノードアプリで「このアプリにはデフォルトの言語が検出されませんでした」エラーがスローされる
-
[解決済み] React with ES7: Uncaught TypeError: Cannot read property 'state' of undefined [duplicate] (未定義のプロパティ'state'を読み込むことはできません。
-
[解決済み】ある要素が可視DOMに存在するかどうかを確認するにはどうすればいいですか?
-
[解決済み】Javascript - ERR_CONTENT_LENGTH_MISMATCH
-
[解決済み】JavaScript ランタイムエラー:'$'が未定義です。
-
[解決済み】React-Routerの子が1つしかない。
-
[解決済み】DOMException: サポートされているソースが見つからなかったため、読み込みに失敗しました。
-
[解決済み】WebSocket接続に失敗しました。WebSocket のハンドシェイク中にエラーが発生しました。予期しない応答コードです。400
-
[解決済み】このオブジェクトの "forEach "はなぜ関数でないのですか?
-
[解決済み】 \u003C とは何ですか?