Ruby on Rails Direct AWS S3 Upload with JqueryFileUpload
我想为我的网站构建一个简单的文件上传系统(仅我将要访问和上传)以上传我的投资组合页面。我的网站是在Heroku上托管的Ruby on Rails上。
因此,我遵循Heroku教程将图像上传到S3。它使用
1 | Bad Request 400: Bucket POST must contain a field named 'key'. If it is specified, please check the order of the fields. |
PortfolioController
1 2 3 4 | def new @s3_direct_post = S3_BUCKET.presigned_post(key:"${filename}", success_action_status: 201, acl: :public_read) @portfolio = Portfolio.new() end |
在视图中检查javascript
1 2 3 4 5 6 7 8 9 10 11 12 | ... fileInput.fileupload({ formData: '<%=@s3_direct_post.fields.to_json.html_safe %>', fileInput: fileInput, url: '<%=@s3_direct_post.url%>', type: 'POST', autoUpload: true, paramName: 'file', dataType: 'XML', replaceFileInput: false, ... |
给予:
1 2 3 4 5 6 7 8 | { "AWSAccessKeyId"=>"my-access-key", "key"=>"${filename}", "policy"=>"long-string", "signature"=>"randomg-signature-string", "success_action_status"=>"201", "acl"=>"public-read" } |
我尝试添加以同步我的时间,如
1 2 3 4 5 6 | AWS.config(access_key_id: ENV['AWS_ACCESS_KEY_ID'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']) AWS::S3.const_set('DEFAULT_HOST',"s3-ap-southeast-1.amazonaws.com") S3_BUCKET = AWS::S3.new.buckets[ENV['S3_BUCKET']] |
浏览Google和Stackoverflow之后,看来Jquery可能正在重建表单数据,从而弄乱了POST值的顺序。
问题是,我对Ruby on Rails和Java较不熟悉,所以我不确定如何解决此问题。
任何建议,我们将不胜感激。谢谢!
我最近正在处理相同的问题,这是解决方案:
您只需更改此
1 | formData: '<%=@s3_direct_post.fields.to_json.html_safe %>' |
对此:
1 | formData: <%=@s3_direct_post.fields.to_json.html_safe %> |
因为
1 | {"key":"value","key":"value","key":"value"} |
并通过将其package在
1 | '{"key":"value","key":"value","key":"value"}' |
哪个不是有效的JSON
另一种解决方案(但效率不高,因为我认为第一种更优雅)
通过查看jquery文件上传文档,它说:
By default, the plugin calls jQuery's serializeArray method on the
upload form to gather additional form data for all input fields
(including hidden fields)
因此您可以将这些字段添加到表单中(在文件输入之前),如下所示:
1 2 3 4 5 6 7 | <% @s3_direct_post.fields.map do |name, value| %> <input type="hidden" name="<%= name %>" value="<%= value %>" /> <% end %> <%= f.file_field :avatar_url%> ... ... |
但是请注意,因为正如文档所述,它将收集所有字段,包括隐藏字段(在Rails应用程序中,还有一些其他隐藏字段,例如utf8和authenticity_token),这会给您带来错误,因为Amazon S3不会接受该错误!
这是我要解决的一个小技巧:
制作与初始表单不同的表单,并为其分配一个ID,在我的情况下,该ID为fields-for-s3
1 2 3 4 5 6 7 8 | <form id="fields-for-s3"> <% @s3_direct_post.fields.map do |name, value| %> <input type="hidden" name="<%= name %>" value="<%= value %>" /> <% end %> </form> <%= form_for @user, ..... %> .... <% end %> |
然后在表单(具有特定ID)上使用jQuery serializeArray()方法手动创建formData对象,如下所示:
1 | formData: $('form#fields-for-s3').serializeArray() |
我希望有帮助。
我遇到了同样的问题:
你也可以打电话
JSON.parse(formdata);
来自您的javascript。
我决定改用Paperclip Heroku教程,并能够成功上传到S3。
希望这对遇到相同问题的人有所帮助。