Dans un projet Node.js, j'essaie de récupérer des données de S3.
Quand j'utilise getSignedURL
, tout fonctionne:
aws.getSignedUrl('getObject', params, function(err, url){
console.log(url);
});
Mes paramètres sont:
var params = {
Bucket: "test-aws-imagery",
Key: "TILES/Level4/A3_B3_C2/A5_B67_C59_Tiles.par"
Si je prends la sortie URL dans la console et la colle dans un navigateur Web, il télécharge le fichier dont j'ai besoin.
Cependant, si j'essaye d'utiliser, getObject
j'obtiens toutes sortes de comportements étranges. Je pense que je ne l'utilise pas correctement. Voici ce que j'ai essayé:
aws.getObject(params, function(err, data){
console.log(data);
console.log(err);
});
Les sorties:
{
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
Il semble donc que cela fonctionne correctement. Cependant, lorsque je mets un point d'arrêt sur l'un des console.log
s, mon IDE (NetBeans) renvoie une erreur et refuse d'afficher la valeur des données. Bien que cela puisse être juste l'IDE, j'ai décidé d'essayer d'autres façons d'utiliser getObject
.
aws.getObject(params).on('httpData', function(chunk){
console.log(chunk);
}).on('httpDone', function(data){
console.log(data);
});
Cela ne produit rien. Mettre un point d'arrêt dans montre que le code n'atteint jamais aucun des console.log
s. J'ai aussi essayé:
aws.getObject(params).on('success', function(data){
console.log(data);
});
Cependant, cela ne produit rien non plus et le fait de placer un point d'arrêt montre que le console.log
n'est jamais atteint.
Qu'est-ce que je fais mal?
la source
aws
objet est-il réellement une nouvelle instance de l'aws.S3
objet? De plus, la réponsegetObject()
est-elle renvoyée à une réponse http ou est-elle redirigée vers un fichier?aws = new AWS.S3()
. La réponse ne doit pas être redirigée vers un fichier. Je dois l'utiliser dans le JavascriptgetObject()
appel. Si vous essayez de transmettre une URL signée à getObject, je ne pense pas que cela fonctionnera.Réponses:
Lorsque vous effectuez une opération à
getObject()
partir de l'API S3, selon les documents, le contenu de votre fichier se trouve dans laBody
propriété, que vous pouvez voir à partir de votre exemple de sortie. Vous devriez avoir un code qui ressemble à ceciconst 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 });
Vous n'aurez peut-être pas besoin de créer un nouveau tampon à partir de l'
data.Body
objet, mais si vous en avez besoin, vous pouvez utiliser l'exemple ci-dessus pour y parvenir.la source
Buffer
objet que je ne connais pas. Théoriquement, je pourrais utilisernew Buffer(data.Body).toString('utf-8');
pour accéder au contenu?data.Body.toString('utf-8');
. Un tampon est une représentation de données binaires dans un nœud, si vous avez besoin de plus d'informations, voici la documentation.toString('utf8')
lors de l'accèsdata.Body
à.toString('binary')
si vous voulez une chaîne binaire pour les images. Si leBuffer
indata.Body
n'a pas besoin d'être converti en chaîne comme dans cette question, vous pouvez simplement revenirdata.Body
et travailler avec leBuffer
directement.Basé sur la réponse de @peteb, mais en utilisant
Promises
etAsync/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(...);
la source
getObject()
est une fonction asynchrone, avez-vous essayé de l'appeler avecawait getObject(...)
?Pour quelqu'un qui recherche une
NEST JS TYPESCRIPT
version de ce qui précède:/** * 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); } }
la source
Vous pouvez également utiliser la bibliothèque 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) }) })
Clause de non-responsabilité: Je travaille pour Minio Son stockage d'objets open source, compatible S3 écrit en golang avec des bibliothèques clientes disponibles en Java , Python , Js , golang .
la source
À première vue, il ne semble pas que vous fassiez quelque chose de mal, mais vous ne montrez pas tout votre code. Ce qui suit a fonctionné pour moi lorsque j'ai vérifié pour la première fois S3 et 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()); }); } });
la source