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

5
我有一个拖放功能,可以将文件转换为Base64数据。之前,它上传到支持Base64上传的Imgur,现在我正在努力转移到Amazon S3。
我看到了人们使用XMLHTTP请求和CORS上传数据到S3的示例,我使用Amazon的AWS S3 SDK gem来避免签署策略和其他事项,因为gem会代替我完成这些工作。所以,我发送Base64数据给本地控制器方法,该方法使用gem上传到S3。
我看到的其他使用Ajax的帖子显示S3支持原始数据上传,但是这个gem似乎不支持,因为每当我查看上传时,我都会得到损坏的图像。我是否上传错误?数据格式是否正确?我尝试过基本的Base64、atob Base64和blob urls,但迄今为止没有任何效果。
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");
            }
        });
    }

控制器方法:

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

编辑:

为了明确,我尝试了几种不同的格式,上面显示的是解码后的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");
            }
        });

一个 Blob URL 看起来像这样:

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});
}
1个回答

7

我是否正确理解您正在:

  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

我已尝试使用JavaScript的atob函数解码数据,但我也会在服务器端尝试。 - Polyov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接