我正在尝试使用meteor为Amazon S3构建图像上传器。感谢Hubert OG,我发现AWS-SDK让事情变得简单。
我的问题是上传的数据似乎已损坏。当我下载文件时,文件可能已损坏。可能是。
将数据插入到图像src中,确实有效,并且图像的预览显示为原样,因此原始文件以及数据可能正确。
我正在使用FileReader加载文件,而不是将结果数据传递给AWS-SDK putObject方法。
var file=template.find('[type=file]').files[0];
var key="uploads/"+file.name;
var reader=new FileReader();
reader.onload=function(event){
var data=event.target.result;
template.find('img').src=data;
Meteor.call("upload_to_s3",file,"uploads",reader.result);
};
reader.readAsDataURL(file);
这是服务器上的方法:
"upload_to_s3":function(file,folder,data){
s3 = new AWS.S3({endpoint:ep});
s3.putObject(
{
Bucket: "myportfoliositebucket",
ACL:'public-read',
Key: folder+"/"+file.name,
ContentType: file.type,
Body:data
},
function(err, data) {
if(err){
console.log('upload error:',err);
}else{
console.log('upload was succesfull',data);
}
}
);
}
答案 0 :(得分:3)
我将npm模块包装为智能包:https://atmosphere.meteor.com/package/s3policies
有了它,您可以制作一个返回写策略的Meteor方法,使用该策略,您可以使用ajax调用上传到S3。
示例:
Meteor.call('s3Upload', name, function (error, policy) {
if(error)
onFinished({error: error});
var formData = new FormData();
formData.append("AWSAccessKeyId", policy.s3Key);
formData.append("policy", policy.s3PolicyBase64);
formData.append("signature", policy.s3Signature);
formData.append("key", policy.key);
formData.append("Content-Type", policy.mimeType);
formData.append("acl", "private");
formData.append("file", file);
$.ajax({
url: 'https://s3.amazonaws.com/' + policy.bucket + '/',
type: 'POST',
xhr: function() { // custom xhr
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress',
function (e){
if(e.lengthComputable)
onProgressUpdate(e.loaded / e.total * 100);
}, false); // for handling the progress of the upload
}
return myXhr;
},
success: function () {
// file finished uploading
},
error: function () { onFinished({error: arguments[1]}); },
processData: false,
contentType: false,
// Form data
data: formData,
cache: false,
xhrFields: { withCredentials: true },
dataType: 'xml'
});
});
编辑:
行formData.append("file", file);
中的“file”变量来自与此类似的行:var file = document.getElementById('fileUpload').files[0];
服务器端代码如下所示:
Meteor.methods({
s3Upload: function (name) {
var myS3 = new s3Policies('my key', 'my secret key');
var location = Meteor.userId() + '/' + moment().format('MMM DD YYYY').replace(/\s+/g, '_') + '/' + name;
if(Meteor.userId()) {
var bucket = 'my bucket';
var policy = myS3.writePolicy(location, bucket, 10, 4096);
policy.key = location;
policy.bucket = bucket;
policy.mimeType = mime.lookup(name);
return policy;
}
}
});
答案 1 :(得分:0)
正文应转换为缓冲区 - 请参阅the documentation。
因此,您应该Body: data
而不是Body: new Buffer(data, 'binary')
。