In einem Node.js-Projekt versuche ich, Daten von S3 zurückzugewinnen.
Wenn ich benutze getSignedURL
, funktioniert alles:
aws.getSignedUrl('getObject', params, function(err, url){
console.log(url);
});
Meine Parameter sind:
var params = {
Bucket: "test-aws-imagery",
Key: "TILES/Level4/A3_B3_C2/A5_B67_C59_Tiles.par"
Wenn ich die URL-Ausgabe in die Konsole nehme und in einen Webbrowser einfüge, wird die benötigte Datei heruntergeladen.
Wenn ich jedoch versuche zu verwenden, getObject
bekomme ich alle möglichen merkwürdigen Verhaltensweisen. Ich glaube, ich benutze es nur falsch. Folgendes habe ich versucht:
aws.getObject(params, function(err, data){
console.log(data);
console.log(err);
});
Ausgänge:
{
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
Es scheint also, dass dies richtig funktioniert. Wenn ich jedoch einen Haltepunkt auf eines der console.log
s setze , gibt meine IDE (NetBeans) einen Fehler aus und weigert sich, den Wert von Daten anzuzeigen. Obwohl dies nur die IDE sein könnte, habe ich mich entschlossen, andere Verwendungsmöglichkeiten auszuprobieren getObject
.
aws.getObject(params).on('httpData', function(chunk){
console.log(chunk);
}).on('httpDone', function(data){
console.log(data);
});
Dies gibt nichts aus. Das Einfügen eines Haltepunkts zeigt, dass der Code niemals eines der console.log
s erreicht. Ich habe auch versucht:
aws.getObject(params).on('success', function(data){
console.log(data);
});
Dies gibt jedoch auch nichts aus und das Platzieren eines Haltepunkts zeigt, dass der console.log
nie erreicht wird.
Was mache ich falsch?
quelle
aws
Objekt tatsächlich eine neue Instanz desaws.S3
Objekts? Wird die Antwort auchgetObject()
an eine http-Antwort zurückgegeben oder an eine Datei weitergeleitet?aws = new AWS.S3()
. Die Antwort sollte nicht an eine Datei weitergeleitet werden. Ich muss es im Javascript verwendengetObject()
Aufruf verwenden. Wenn Sie versuchen, eine signierte URL an getObject zu übergeben, funktioniert das meiner Meinung nach nicht.Antworten:
Wenn Sie eine
getObject()
über die S3-API ausführen, befindet sich der Inhalt Ihrer Datei gemäß den Dokumenten in derBody
Eigenschaft, die Sie anhand Ihrer Beispielausgabe sehen können. Sie sollten Code haben, der ungefähr so aussiehtconst 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 });
Möglicherweise müssen Sie keinen neuen Puffer aus dem
data.Body
Objekt erstellen. Wenn Sie dies benötigen, können Sie das obige Beispiel verwenden, um dies zu erreichen.quelle
Buffer
Objekt zu sein, mit dem ich nicht vertraut bin. Theoretisch könnte ich verwendennew Buffer(data.Body).toString('utf-8');
, um zum Inhalt zu gelangen?data.Body.toString('utf-8');
. Ein Puffer ist eine Darstellung von Binärdaten im Knoten. Wenn Sie weitere Informationen benötigen, finden Sie hier die Dokumente.toString('utf8')
beim Zugriffdata.Body
auf,.toString('binary')
wenn Sie eine Binärzeichenfolge für Bilder möchten. Wenn dasBuffer
Indata.Body
nicht wie in dieser Frage in einen String konvertiert werden muss, können Sie einfach zurückkehrendata.Body
undBuffer
direkt mit dem arbeiten .Basierend auf der Antwort von @peteb, aber mit
Promises
undAsync/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(...);
quelle
getObject()
ist eine asynchrone Funktion. Haben Sie versucht, sie aufzurufenawait getObject(...)
?Für jemanden, der nach einer
NEST JS TYPESCRIPT
Version der oben genannten sucht :/** * 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); } }
quelle
Alternativ können Sie die minio-js-Clientbibliothek get-object.js verwenden
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) }) })
Haftungsausschluss: Ich arbeite für Minio. Sein Open-Source-S3-kompatibler Objektspeicher wurde in Golang mit Client-Bibliotheken geschrieben, die in Java , Python , Js und Golang verfügbar sind .
quelle
Auf den ersten Blick sieht es nicht so aus, als ob Sie etwas falsch machen, aber Sie zeigen nicht Ihren gesamten Code. Folgendes funktionierte für mich, als ich S3 und Node zum ersten Mal auscheckte:
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()); }); } });
quelle