我正试图使用Node.js将一张图片上传到Amazon S3存储桶。最终,我想能够将图片推送到S3,然后能够访问该S3 URL并在浏览器中查看图片。我使用Curl查询执行HTTP POST请求,将图片作为正文发送:
curl -kvX POST --data-binary "@test.jpg" 'http://localhost:3031/upload/image'
然后在Node.js方面,我做了以下操作:
exports.pushImage = function(req, res) {
var image = new Buffer(req.body);
var s3bucket = new AWS.S3();
s3bucket.createBucket(function() {
var params = {Bucket: 'My/bucket', Key: 'test.jpg', Body: image};
// Put the object into the bucket.
s3bucket.putObject(params, function(err) {
if (err) {
res.writeHead(403, {'Content-Type':'text/plain'});
res.write("Error uploading data");
res.end()
} else {
res.writeHead(200, {'Content-Type':'text/plain'});
res.write("Success");
res.end()
}
});
});
};
我的文件在Amazon S3上显示为0字节。我该如何使用Node.js将二进制文件上传到S3?我在处理二进制数据和缓冲区方面做错了什么?更新:
我找到了需要做的事情。应该首先更改curl查询。这是工作正常的命令:
curl -kvX POST -F foobar=@my_image_name.jpg 'http://localhost:3031/upload/image'
然后,我添加了一行将其转换为流的代码。这是可用的代码:
exports.pushImage = function(req, res) {
var image = new Buffer(req.body);
var s3bucket = new AWS.S3();
s3bucket.createBucket(function() {
var bodyStream = fs.createReadStream(req.files.foobar.path);
var params = {Bucket: 'My/bucket', Key: 'test.jpg', Body: bodyStream};
// Put the object into the bucket.
s3bucket.putObject(params, function(err) {
if (err) {
res.writeHead(403, {'Content-Type':'text/plain'});
res.write("Error uploading data");
res.end()
} else {
res.writeHead(200, {'Content-Type':'text/plain'});
res.write("Success");
res.end()
}
});
});
};
因此,为了将文件上传到API端点(使用Node.js和Express),并让API将该文件推送到Amazon S3,首先需要填充“files”字段执行POST请求。文件最终出现在API侧,在那里它可能存储在某个临时目录中。Amazon的S3 putObject方法需要流,因此您需要通过向'fs'模块提供上传文件所在路径来创建读取流。
我不知道这是否是上传数据的正确方式,但它可行。有人知道是否有一种方法在请求正文中POST二进制数据,并让API将其发送到S3吗?我不太清楚多部分上传与标准POST到正文之间的区别。
fs.stat(req.body)
获取文件大小,然后使用fs.createReadStream(req.body)
创建一个流,然后将其作为Body
参数传递给 S3。 - drivativfs.stat(req.body)
报错,需要一个字符串(req.body
是二进制数据,不是字符串)。如果我将二进制的 .jpg 转换为字符串,那么后续就无法使用 Web 浏览器访问它了。 - Jack