В проекте 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
s, моя 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
никогда не достигается.
Что я делаю не так?
источник
aws
объект является новым экземпляромaws.S3
объекта? КромеgetObject()
того, передается ли ответ обратно в HTTP-ответ или он передается в файл?aws = new AWS.S3()
. Ответ не должен передаваться в файл. Мне нужно использовать его в JavascriptgetObject()
звонке. Если вы пытаетесь передать подписанный URL-адрес getObject, я не думаю, что это сработает.Ответы:
При выполнении a
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
объекта, но при необходимости вы можете использовать приведенный выше образец для этого.источник
Buffer
мне незнакомым объектом. Теоретически я мог бы использовать,new Buffer(data.Body).toString('utf-8');
чтобы добраться до контента?data.Body.toString('utf-8');
. Буфер - это представление двоичных данных в узле, если вам нужна дополнительная информация, вот документы.toString('utf8')
при доступеdata.Body
к,.toString('binary')
если вам нужна двоичная строка для изображений. ЕслиBuffer
indata.Body
не нужно преобразовывать в String, как в этом вопросе, вы можете просто вернутьсяdata.Body
и работать с нимBuffer
напрямую.На основе ответа @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(...);
источник
getObject()
- это асинхронная функция, вы пробовали вызывать ееawait getObject(...)
?Для тех, кто ищет
NEST JS TYPESCRIPT
версию вышеперечисленного:/** * 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); } }
источник
В качестве альтернативы вы можете использовать клиентскую библиотеку 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. Это хранилище объектов с открытым исходным кодом, совместимое с S3, написанное на golang, с клиентскими библиотеками, доступными на Java , Python , Js , golang .
источник
На первый взгляд не похоже, что вы делаете что-то не так, но вы не показываете весь свой код. Когда я впервые проверял 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()); }); } });
источник