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)
我是否正确地读到你:
如果是这种情况,则需要先将步骤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)