通过AWS Ruby SDK将Base64图像数据上传到S3

Pol*_*yov 5 javascript ruby ruby-on-rails amazon-s3 amazon-web-services

我有一个拖放功能,它会删除已经删除的文件并将其转换为Base64数据.以前,它上传到Imgur,其API支持Base64上传,现在我正在努力转移到Amazon S3.

我已经看到人们使用XMLHTTP请求和CORS将数据上传到S3的示例,我正在使用亚马逊的AWS S3 SDK gem来避免签署策略和其他事情,因为gem为我做了这些.所以我所做的就是将Base64数据发送到本地控制器metod,它使用gem上传到S3.

使用Ajax的其他帖子我已经看到S3显示S3支持原始数据上传,但是看起来并不好,因为每当我查看上传时我都会看到破碎的图像.我上传的不正确吗?数据格式是否错误?我已经尝试了基本的Base64,atob Base64和blob网址,但到目前为止还没有任何工作.

JS:

fr.onload = function(event) {
        var Tresult = event.target.result;
        var datatype = Tresult.slice(Tresult.search(/\:/)+1,Tresult.search(/\;/));
        var blob = atob(Tresult.replace(/^data\:image\/\w+\;base64\,/, ''));
        $.ajax({
            type:"POST",
            data:{
                file:blob,
                contentType: datatype,
                extension:datatype.slice(datatype.search(/\//)+1)
            },
            url:'../uploads/images',
            success:function(msg) {
                handleStatus(msg,"success");
            },
            error:function(errormsg) {
                handleStatus(errormsg,"error");
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

控制器方法:

def supload
    s3 = AWS::S3.new(:access_key_id => ENV['S3_KEY'],:secret_access_key => ENV['S3_SECRET'])
    bucket = s3.buckets['bucket-name']
    data = params[:file].to_s
    type = params[:contentType].to_s
    extension = params[:extension].to_s
    name = ('a'..'z').to_a.shuffle[0..7].join + ".#{extension}"
    obj = bucket.objects.create(name,data,{content_type:type,acl:"public_read"})
    url = obj.public_url().to_s
    render text: url
end
Run Code Online (Sandbox Code Playgroud)

编辑:

为了清楚起见,我尝试了几种不同的格式,上面显示的格式是base64.常规Base64如下所示:

        var Tresult = event.target.result;
        var datatype = Tresult.slice(Tresult.search(/\:/)+1,Tresult.search(/\;/));
        var blob = Tresult;
        $.ajax({
            type:"POST",
            data:{
                file:blob,
                mimeType: datatype,
                extension:datatype.slice(datatype.search(/\//)+1)
            },
            url:'../uploads/images',
            success:function(msg) {
                handleStatus(msg,"success");
            },
            error:function(errormsg) {
                handleStatus(errormsg,"error");
            }
        });
Run Code Online (Sandbox Code Playgroud)

并且blob网址看起来像这样:

var blob = URL.createObjectURL(dataURItoBlob(Tresut,datatype));
...
function dataURItoBlob(dataURI, dataType) {
    var binary = atob(dataURI.split(',')[1]);
    var array = [];
    for(var i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], {type: dataType});
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*son 6

我是否正确地读到你:

  1. 使用AJAX将Base64编码的文件发送到Rails
  2. 使用Rails将文件上传到S3
  3. 在S3中查看文件?

如果是这种情况,则需要先将步骤2中的数据解码,然后再将其发送到S3.像这样的东西可能会起作用:

require "base64"
def supload
    s3 = AWS::S3.new(:access_key_id => ENV['S3_KEY'],:secret_access_key => ENV['S3_SECRET'])
    bucket = s3.buckets['bucket-name']
    data = Base64.decode64(params[:file].to_s)
    type = params[:contentType].to_s
    extension = params[:extension].to_s
    name = ('a'..'z').to_a.shuffle[0..7].join + ".#{extension}"
    obj = bucket.objects.create(name,data,{content_type:type,acl:"public_read"})
    url = obj.public_url().to_s
    render text: url
end
Run Code Online (Sandbox Code Playgroud)