我在尝试将文件上传到S3存储桶时遇到了问题 . 除了我的文件参数看起来不合适之外,一切正常 . 我正在使用Amazon S3 sdk从nodejs上传到s3 .
这些是我的路线设置:
var multiparty = require('connect-multiparty'),
multipartyMiddleware = multiparty();
app.route('/api/items/upload').post(multipartyMiddleware, items.upload);
这是items.upload()函数:
exports.upload = function(req, res) {
var file = req.files.file;
var s3bucket = new AWS.S3({params: {Bucket: 'mybucketname'}});
s3bucket.createBucket(function() {
var params = {
Key: file.name,
Body: file
};
s3bucket.upload(params, function(err, data) {
console.log("PRINT FILE:", file);
if (err) {
console.log('ERROR MSG: ', err);
} else {
console.log('Successfully uploaded data');
}
});
});
};
将 Body
param设置为类似 "hello"
的字符串可以正常工作 . 根据doc, Body
param必须采用(Buffer,Typed Array,Blob,String,ReadableStream)对象数据 . 但是,上载文件对象失败,并显示以下错误消息:
[Error: Unsupported body payload object]
这是文件对象:
{ fieldName: 'file',
originalFilename: 'second_fnp.png',
path: '/var/folders/ps/l8lvygws0w93trqz7yj1t5sr0000gn/T/26374-7ttwvc.png',
headers:
{ 'content-disposition': 'form-data; name="file"; filename="second_fnp.png"',
'content-type': 'image/png' },
ws:
{ _writableState:
{ highWaterMark: 16384,
objectMode: false,
needDrain: true,
ending: true,
ended: true,
finished: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
errorEmitted: false },
writable: true,
domain: null,
_events: { error: [Object], close: [Object] },
_maxListeners: 10,
path: '/var/folders/ps/l8lvygws0w93trqz7yj1t5sr0000gn/T/26374-7ttwvc.png',
fd: null,
flags: 'w',
mode: 438,
start: undefined,
pos: undefined,
bytesWritten: 261937,
closed: true },
size: 261937,
name: 'second_fnp.png',
type: 'image/png' }
任何帮助将不胜感激!
4 回答
所以看起来这里有一些问题 . 根据您的帖子,您似乎尝试使用
connect-multiparty
中间件支持文件上传 . 这个中间件的作用是获取上传的文件,将其写入本地文件系统,然后将req.files
设置为上传的文件 .您的路线配置看起来很好,问题似乎与您的
items.upload()
功能有关 . 特别是这部分:正如我在回答的开头提到的
connect-multiparty
将文件写入本地文件系统,因此您需要打开文件并读取它,然后上传它,然后在本地文件系统上删除它 .那说你可以将你的方法更新为如下所示:
这样做是从本地文件系统读取上传的文件,然后将其上传到S3,然后删除临时文件并发送响应 .
这种方法存在一些问题 . 首先,它没有那么高效,因为对于大文件,您将在编写之前加载整个文件 . 其次,这个过程不支持大文件的多部分上传(我认为在你必须进行多部分上传之前,截止值是5 Mb) .
我建议的是你使用我一直在研究的模块S3FS,它提供了与Node.JS中原生FS类似的接口,但抽象了一些细节,如多部分上传和S3 api (以及添加一些额外的功能,如递归方法) .
如果你要拉入S3FS库,你的代码看起来像这样:
这将做的是实例化所提供的存储桶和AWS凭据的模块,然后创建存储桶(如果它不存在) . 然后,当请求通过上传文件时,我们将打开一个流到该文件并使用它将文件写入S3到指定的路径 . 这将在幕后处理多部分上传部分(如果需要),并且具有通过流完成的好处,因此您无需等待在开始上载之前读取整个文件 .
如果您愿意,可以将代码更改为Promises的回调 . 或者将pipe()方法与事件侦听器一起使用以确定结束/错误 .
如果您正在寻找其他方法,请查看s3fs的文档,如果您正在寻找其他方法或遇到问题,请随时打开问题 .
我发现以下是一个有效的解决方案::
安装aws-sdk后,使用以下代码将值替换为您需要的值 .
如果您正在寻找参考资料,我在这里找到了关于这个主题的完整教程::
How to upload files (text/image/video) in amazon s3 using node.js
或使用承诺: