admin管理员组文章数量:1326474
I've got a drag and drop function which takes the file that's been dropped on it and converts it to Base64 data. Before, it was uploading to Imgur, whose API supports Base64 uploads, and now I'm working on moving to Amazon S3.
I've seen examples of people using XMLHTTP requests and CORS to upload data to S3, I'm using Amazon's AWS S3 SDK gem to avoid having to sign policies and other things, as the gem does that for me. So what I've done is send the Base64 data to a local controller metod which uses the gem to upload to S3.
The other posts using Ajax i've seen show that S3 supports raw data uploads, but the gem doesn't seem to, as whenever I view the uploads i get broken images. Am I uploading it incorrectly? Is the data in the wrong format? I've tried the basic Base64, atob Base64, and blob urls, but nothing works so far.
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");
}
});
}
Controller method:
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
Edit:
To be clear, I've tried a couple of different formats, the one displayed above is decoded base64. Regular Base64 looks like this:
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");
}
});
and a blob url looks like this:
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});
}
I've got a drag and drop function which takes the file that's been dropped on it and converts it to Base64 data. Before, it was uploading to Imgur, whose API supports Base64 uploads, and now I'm working on moving to Amazon S3.
I've seen examples of people using XMLHTTP requests and CORS to upload data to S3, I'm using Amazon's AWS S3 SDK gem to avoid having to sign policies and other things, as the gem does that for me. So what I've done is send the Base64 data to a local controller metod which uses the gem to upload to S3.
The other posts using Ajax i've seen show that S3 supports raw data uploads, but the gem doesn't seem to, as whenever I view the uploads i get broken images. Am I uploading it incorrectly? Is the data in the wrong format? I've tried the basic Base64, atob Base64, and blob urls, but nothing works so far.
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");
}
});
}
Controller method:
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
Edit:
To be clear, I've tried a couple of different formats, the one displayed above is decoded base64. Regular Base64 looks like this:
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");
}
});
and a blob url looks like this:
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});
}
Share
Improve this question
edited May 23, 2017 at 10:31
CommunityBot
11 silver badge
asked Jun 24, 2014 at 20:40
PolyovPolyov
2,3213 gold badges26 silver badges36 bronze badges
1 Answer
Reset to default 7Am I reading this right that you are:
- Using AJAX to send a Base64-encoded file to Rails
- Using Rails to upload the file to S3
- Viewing the file in S3?
If that's the case, you need to decode the data in step 2 before sending it on to S3. Something like this might work:
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
本文标签: javascriptUploading Base64 image data to S3 via AWS Ruby SDKStack Overflow
版权声明:本文标题:javascript - Uploading Base64 image data to S3 via AWS Ruby SDK - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742208347a2433236.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论