Друзья часто спрашивают меня, как загружать файлы на сервер при помощи 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 |
Просто, не правда ли?

[...] http://kpumuk.info/ruby-on-rails/in-place-file-upload-with-ruby-on-rails/ [...]
Есть плугин для jQuery, который использует похожую технику.