1

Я хочу создать простую систему загрузки файлов для моего сайта (только я получаю доступ и загрузку), чтобы загрузить мою страницу портфолио. Мой сайт находится на Ruby on Rails, размещенном на Heroku.Ruby on Rails Direct AWS S3 Загрузка с помощью JqueryFileUpload

Итак, я следил за Heroku Tutorial, чтобы загрузить изображения на S3. Он использует жемчужину aws-sdk. После изучения учебника, когда я пытаюсь загрузить простой .png-файл, я получил следующую ошибку.

Bad Request 400: Bucket POST must contain a field named 'key'. If it is specified, please check the order of the fields. 

PortfolioController

def new 
    @s3_direct_post = S3_BUCKET.presigned_post(key: "${filename}", success_action_status: 201, acl: :public_read) 
    @portfolio = Portfolio.new() 
    end 

Проверка яваскрипт formData значения в Виде:

... 
fileInput.fileupload({ 
       formData:  '<%[email protected]_direct_post.fields.to_json.html_safe %>', 
       fileInput:  fileInput, 
       url:   '<%[email protected]_direct_post.url%>', 
       type:   'POST', 
       autoUpload:  true, 
       paramName:  'file', 
       dataType:  'XML', 
       replaceFileInput: false, 

... 

дает:

{ 
"AWSAccessKeyId"=>"my-access-key", 
"key"=>"${filename}", 
"policy"=> "long-string", 
"signature"=>"randomg-signature-string", 
"success_action_status"=>"201", 
"acl"=>"public-read" 
} 

Я пытался добавить синхронизировать мой выбор времени, как показано в /config/initializers/aws.rb:

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 и Javascript, поэтому я не уверен, как это сделать.

Любые советы приветствуются. Благодаря!

+1

Я столкнулся с той же проблемой, я решил объединить загрузку изображения с формой и включить в нее все необходимые параметры (ключ, политика, acl и т. Д.) В качестве скрытых элементов ввода. Затем удалите строку formData: '<...>' из файла js, и плагин будет использовать данные формы в порядке на странице.Я столкнулся с одной проблемой, когда подпись была пустой в форме, но так как я смог получить @ s3_direct_post.fields на странице, я заполнил ввод сигнатурой оттуда перед отправкой загрузки изображения. – blaedj

ответ

0

Вместо этого я решил следовать за Paperclip Heroku Tutorial и смог успешно загрузить его на S3.

Надеюсь, это поможет любому, у кого есть такая же проблема.

1

я имел дело в последнее время с той же проблемой, и это решение:

Вам нужно только изменить

formData: '<%[email protected]_direct_post.fields.to_json.html_safe %>' 

к этому:

formData: <%[email protected]_direct_post.fields.to_json.html_safe %> 

Поскольку @s3_direct_post.fields.to_json.html_safe даст вам что-то вроде этого:

{"key":"value", "key":"value", "key":"value"} 

и обертывание, что между ' ' он будет делать это следующим образом:

'{"key":"value", "key":"value", "key":"value"}' 

Который не является допустимым JSON

Другое решение (но не эффективен, потому что первый более элегантный, я думаю)

глядя на Jquery файл загрузить documentation он говорит:

По умолчанию плагин вызывает метод serializeArray Jquery по форме в загрузки, чтобы собрать дополнительные данные формы для всех полей ввода (включая скрытые поля)

Таким образом, вы можете добавить эти поля в форме (до ввод файл), как это:

<% @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 этого не примет!

Это немного хака я сделал, чтобы решить, что:

Сделать отдельную форму, чем ваша первоначальная форма, и присвоить идентификатор к нему, в моем случае идентификатор полей-для-s3

<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 %> 

Затем с помощью метода JQuery serializeArray() на форме (с конкретным ID), чтобы создать FormData объект вручную, как это:

formData: $('form#fields-for-s3').serializeArray() 

Я надеюсь, что эта помощь.

0

Я столкнулся с той же проблемой: Вы также можете позвонить: JSON.parse (formdata); С вашего javascript.

Смежные вопросы