Загрузка файлов без обновления страницы в Ruby on Rails

Posted by Dmytro Shteflyuk on under Ruby & Rails · English (94,527 views)

Друзья часто спрашивают меня, как загружать файлы на сервер при помощи AJAX, и обычно получают ответ “никак”. Ответ, конечно, правильный, но что если действительно нужно загрузить файл без полного обновления страницы? И, конечно, в этом случае хотелось бы использовать RJS. В этой заметке я расскажу, что делать, чтобы получить эффект, похожий на загрузку файлов при помощи AJAX (кстати, Gmail использует эту технику).

Для начала, знаете ли вы, что у элемента form есть атрибут target? Если указать его, данные формы будут отправлены во фрейм, название которого указано в атрибуте target. Конечно, возможно использовать iframe, причем он может быть скрытым! Взгляните на следующий HTML:

1
2
3
4
5
<form target="upload_frame" action="/test/upload_action" id="upload_form" method="post" enctype="multipart/form-data">
  <input type="file" name="uploaded_file" /><br />
  <input type="submit" />
</form>
<iframe id="upload_frame" name="upload_frame" style="display: none"></iframe>

Когда вы нажмете кнопку “Submit”, форма будет отправлена в скрытый iframe, и будет вызван соответствующий метод контроллера на сервере. Но результирующий RJS вернется в скрытый фрейм! Необходимо получить результирующие данные и выполнить их в контексте всей страницы (родительского окна для фрейма). Существует одна интересная техника: Remote Scripting with IFRAME, и ее реализация в виде плагина Ruby on Rails здесь. Все, что необходимо, это обернуть render в блок responds_to_parent. Пример использования:

1
2
3
4
5
6
7
8
9
10
11
class TestController < ActionController::Base
  def upload_action
    # Do stuff with params[:uploaded_file]

    responds_to_parent do
      render :update do |page|
        page.replace_html 'upload_form', :partial => 'upload_form'
      end
    end
  end
end

Просто, не правда ли?

32 Responses to this entry

Subscribe to comments with RSS

exip
said on Ноябрь 21, 2008 at 18:31 · Permalink

Есть плугин для jQuery, который использует похожую технику.

More comments: 1 2

Comments are closed

Comments for this entry are closed for a while. If you have anything to say – use a contact form. Thank you for your patience.