Javascript 如何从 Node.js 中的 S3 getObject 获得响应?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36942442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get response from S3 getObject in Node.js?
提问by Sara Tibbetts
In a Node.js project I am attempting to get data back from S3.
在 Node.js 项目中,我试图从 S3 取回数据。
When I use getSignedURL
, everything works:
当我使用时getSignedURL
,一切正常:
aws.getSignedUrl('getObject', params, function(err, url){
console.log(url);
});
My params are:
我的参数是:
var params = {
Bucket: "test-aws-imagery",
Key: "TILES/Level4/A3_B3_C2/A5_B67_C59_Tiles.par"
If I take the URL output to the console and paste it in a web browser, it downloads the file I need.
如果我将 URL 输出带到控制台并将其粘贴到 Web 浏览器中,它会下载我需要的文件。
However, if I try to use getObject
I get all sorts of odd behavior. I believe I am just using it incorrectly. This is what I've tried:
但是,如果我尝试使用,则会出现getObject
各种奇怪的行为。我相信我只是错误地使用它。这是我尝试过的:
aws.getObject(params, function(err, data){
console.log(data);
console.log(err);
});
Outputs:
输出:
{
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
So it appears that this is working properly. However, when I put a breakpoint on one of the console.log
s, my IDE (NetBeans) throws an error and refuses to show the value of data. While this could just be the IDE, I decided to try other ways to use getObject
.
所以看起来这工作正常。但是,当我在其中一个console.log
s上放置断点时,我的 IDE (NetBeans) 会抛出错误并拒绝显示数据的值。虽然这可能只是 IDE,但我决定尝试其他方式来使用getObject
.
aws.getObject(params).on('httpData', function(chunk){
console.log(chunk);
}).on('httpDone', function(data){
console.log(data);
});
This does not output anything. Putting a breakpoint in shows that the code never reaches either of the console.log
s. I also tried:
这不会输出任何内容。放置断点表明代码永远不会到达任何一个console.log
s。我也试过:
aws.getObject(params).on('success', function(data){
console.log(data);
});
However, this also does not output anything and placing a breakpoint shows that the console.log
is never reached.
但是,这也不会输出任何内容,并且放置断点表明console.log
永远不会到达。
What am I doing wrong?
我究竟做错了什么?
回答by peteb
When doing a getObject()
from the S3 API, per the docsthe contents of your file are located in the Body
property, which you can see from your sample output. You should have code that looks something like the following
getObject()
从 S3 API执行 a 时,根据文档,您的文件内容位于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
});
You may not need to create a new buffer from the data.Body
object but if you need you can use the sample above to achieve that.
您可能不需要从data.Body
对象创建新缓冲区,但如果需要,您可以使用上面的示例来实现。
回答by Arian Acosta
Based on the answer by @peteb, but using Promises
and Async/Await
:
基于@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(...);
回答by Chaos Legion
For someone looking for a NEST JS TYPESCRIPT
version of the above:
对于寻找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);
}
}
回答by koolhead17
Alternatively you could use minio-js client libraryget-object.js
或者,您可以使用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)
})
})
Disclaimer: I work for MinioIts open source, S3 compatible object storage written in golang with client libraries available in Java, Python, Js, golang.
免责声明:我为Minio工作,它的开源、S3 兼容对象存储用 golang 编写,客户端库可用Java、Python、Js、golang 编写。
回答by bknights
At first glance it doesn't look like you are doing anything wrong but you don't show all your code. The following worked for me when I was first checking out S3 and Node:
乍一看,您似乎没有做错任何事情,但您没有显示所有代码。当我第一次检查 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());
});
}
});