如何使用meteor将图像从FileReader上传到Amazon s3

时间:2013-10-25 15:00:49

标签: amazon-s3 meteor filereader

我正在尝试使用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);
                }
            }
        );
    }

2 个答案:

答案 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')