使用Rails和jQuery文件上传设置内容类型直接到S3上传 [英] Setting the Content-Type in direct to S3 upload using Rails and jQuery File Upload
问题描述
我见过很多问题在这里就这个话题,但没有我遇到很适合我,所以我在这里张贴的另一个...
I've seen many questions here on this topic but nothing I've come across has worked for me, so here I am posting another...
我在Ruby on Rails的尝试配置文件上传直接到Amazon S3使用 jQuery的文件上传插件一>。我跟着一起非常有帮助 Heroku的教程获取初始设置加工。上传的文件很好,但他们都被标记为内容类型:二进制/八位字节流
在S3中,所以当他们曾在应用程序中,所有的文件会下载,而不是直接打开。
I'm on Ruby on Rails trying to configure file uploads direct to Amazon S3 using the jQuery File Upload plugin. I followed along with the very helpful Heroku tutorial to get the initial setup working. Files uploaded fine, but they were all labeled as Content-Type: binary/octet-stream
in S3, so when they were served in the app, all files would download instead of opening directly.
这是一个问题,因为我试图让图像,PDF文件,音频或视频文件,所以我需要能够抓住正确的内容类型
从该文件,并把它传递给S3。在看在亚马逊的AWS-SDK宝石文档,我看到了<一个href="http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/$p$psignedPost.html#where-instance_method">this部分有关添加。凡(:CONTENT_TYPE).starts_with()
至presigned后对象的末尾修改政策。然而,当我这样做,它抛出一个错误:
This is a problem because I'm trying to allow images, PDFs, audio or video files, so I need to be able to grab the correct Content-Type
from the file and pass it on to S3. In looking at the AWS-SDK gem docs on Amazon, I saw this section about adding .where(:content_type).starts_with("")
to the end of the presigned post object to modify the policy. However, when I did that, it threw an error:
<Error><Code>AccessDenied</Code>
<Message>Invalid according to Policy: Policy Condition failed: ["starts-with", "$Content-Type", ""]</Message>
所以我加入 CONTENT_TYPE:
进入OPTS哈希为presigned post对象,而现在它的作品了,但不是所有的文件默认为二进制/八位字节流
都默认为为image / jpeg
。这是我的code截至目前:
So I added in content_type: ""
into the opts hash for the presigned post object, and now it works again, but instead of all files defaulting to binary/octet-stream
they all default to image/jpeg
. Here's my code as of now:
控制器
def new
@s3_direct_post = S3_BUCKET.presigned_post(
key: "uploads/#{SecureRandom.uuid}/${filename}",
success_action_status: 201,
acl: :public_read,
content_type: "").where(:content_type).starts_with("")
end
_form.html.haml
:javascript
$(function() {
$('.directUpload').find("input:file").each(function(i, elem) {
var fileInput = $(elem);
var form = $(fileInput.parents('form:first'));
var submitButton = form.find('input[type="submit"]');
var progressBar = $("<div class='bar'></div>");
var barContainer = $("<div class='progress'></div>").append(progressBar);
var fd = #{@s3_direct_post.fields.to_json.html_safe};
fileInput.after(barContainer);
fileInput.fileupload({
// This 'add' section is where I thought to set the Content-Type, but I've tried with and without it and Content-Type remains the same on S3
add: function (e, data) {
fd["Content-Type"] = data.files[0].type;
console.log(fd); // The JSON object shows Content-Type correctly in console
data.submit();
},
fileInput: fileInput,
url: '#{@s3_direct_post.url}',
type: 'POST',
autoUpload: true,
formData: fd, // My updated JSON object
paramName: 'file',
dataType: 'XML',
replaceFileInput: false,
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
progressBar.css('width', progress + '%')
},
start: function (e) {
submitButton.prop('disabled', true);
progressBar.
css('background', 'green').
css('display', 'block').
css('width', '0%').
text("Loading...");
},
done: function(e, data) {
submitButton.prop('disabled', false);
progressBar.text("Uploading done");
// extract key and generate URL from response
var key = $(data.jqXHR.responseXML).find("Key").text();
var url = 'https://d295xbrl26r3ll.cloudfront.net/' + key.replace(/ /g, "%20");
// create hidden field
var input = $("<input />", { type:'hidden', name: 'item[file_url]', value: url })
form.append(input);
},
fail: function(e, data) {
submitButton.prop('disabled', false);
progressBar.
css("background", "red").
text("Failed");
}
});
});
});
我如何发送内容类型
妥善S3?
推荐答案
替换为你加挡:
fd["Content-Type"] = data.files[0].type;
data.formData = fd;
data.submit();
回调是正确的,但data.formData已经采取了FD的原始版本。只要重新设置与修改后的FD,你应该是好去。
The callback is correct, but data.formData already took the original version of fd. Just set it again with your modified fd and you should be good to go.
更新控制方法也让你不这样做了两遍:
Update the controller method too so you're not doing it twice:
@s3_direct_post = S3_BUCKET.presigned_post(
key: "uploads/#{SecureRandom.uuid}/${filename}",
success_action_status: 201,
acl: :public_read).where(:content_type).starts_with("")
这篇关于使用Rails和jQuery文件上传设置内容类型直接到S3上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!