Dalam proyek Node.js saya mencoba mendapatkan kembali data dari S3.
Saat saya menggunakan getSignedURL
, semuanya bekerja:
aws.getSignedUrl('getObject', params, function(err, url){
console.log(url);
});
Parameter saya adalah:
var params = {
Bucket: "test-aws-imagery",
Key: "TILES/Level4/A3_B3_C2/A5_B67_C59_Tiles.par"
Jika saya mengambil output URL ke konsol dan menempelkannya di browser web, itu mengunduh file yang saya butuhkan.
Namun, jika saya mencoba menggunakan getObject
saya mendapatkan segala macam perilaku aneh. Saya yakin saya hanya menggunakannya secara tidak benar. Inilah yang saya coba:
aws.getObject(params, function(err, data){
console.log(data);
console.log(err);
});
Keluaran:
{
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
Jadi tampaknya ini berfungsi dengan baik. Namun, ketika saya meletakkan breakpoint pada salah satu console.log
s, IDE saya (NetBeans) membuat kesalahan dan menolak untuk menunjukkan nilai data. Meskipun ini mungkin saja IDE, saya memutuskan untuk mencoba cara lain untuk menggunakannya getObject
.
aws.getObject(params).on('httpData', function(chunk){
console.log(chunk);
}).on('httpDone', function(data){
console.log(data);
});
Ini tidak menghasilkan apa pun. Menempatkan breakpoint di menunjukkan bahwa kode tidak pernah mencapai salah satu dari console.log
s. Saya juga mencoba:
aws.getObject(params).on('success', function(data){
console.log(data);
});
Namun, ini juga tidak menampilkan apa pun dan menempatkan breakpoint menunjukkan bahwa console.log
tidak pernah tercapai.
Apa yang saya lakukan salah?
sumber
aws
objek Anda sebenarnya adalah objek baruaws.S3
? Selain itu, apakah tanggapangetObject()
akan dikirimkan kembali ke tanggapan http atau sedang disalurkan ke file?aws = new AWS.S3()
. Respons tidak boleh disalurkan ke file. Saya perlu menggunakannya di JavascriptgetObject()
panggilan. Jika Anda mencoba meneruskan URL yang ditandatangani ke getObject, saya rasa itu tidak akan berhasil.Jawaban:
Saat melakukan
getObject()
dari S3 API, sesuai dokumen , konten file Anda berada diBody
properti, yang dapat Anda lihat dari output sampel Anda. Anda harus memiliki kode yang terlihat seperti berikut iniconst 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 });
Anda mungkin tidak perlu membuat buffer baru dari
data.Body
objek, tetapi jika perlu, Anda dapat menggunakan contoh di atas untuk melakukannya.sumber
Buffer
objek, yang tidak saya kenal. Secara teoritis saya dapat menggunakannew Buffer(data.Body).toString('utf-8');
untuk mendapatkan konten?data.Body.toString('utf-8');
. Buffer adalah representasi dari data biner dalam node, jika Anda membutuhkan info lebih lanjut di sini adalah docs.toString('utf8')
saat mengaksesdata.Body
ke.toString('binary')
jika Anda menginginkan string biner untuk gambar. JikaBuffer
indata.Body
tidak perlu diubah menjadi String seperti dalam pertanyaan ini, Anda dapat kembalidata.Body
dan bekerja denganBuffer
langsung.Berdasarkan jawaban @peteb, tapi menggunakan
Promises
danAsync/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(...);
sumber
getObject()
adalah fungsi asinkron, apakah Anda mencoba memanggilnya denganawait getObject(...)
?Untuk seseorang yang mencari
NEST JS TYPESCRIPT
versi di atas:/** * 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); } }
sumber
Alternatifnya, Anda bisa menggunakan perpustakaan klien 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) }) })
Penafian: Saya bekerja untuk Minio Sumber terbuka, penyimpanan objek kompatibel S3 yang ditulis dalam golang dengan pustaka klien tersedia di Java , Python , Js , golang .
sumber
Pada pandangan pertama, sepertinya Anda tidak melakukan kesalahan tetapi Anda tidak menampilkan semua kode Anda. Yang berikut ini berhasil bagi saya ketika saya pertama kali memeriksa S3 dan 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()); }); } });
sumber