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

Oct 28
2006 15:10 (AJAX, Программирование, Ruby on Rails) · English (48,506 views)

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

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

<form target="upload_frame" action="/test/upload_action" id="upload_form">
  <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. Пример использования:

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

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

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

Подписаться на комментарии по RSS или TrackBack на 'Загрузка файлов без обновления страницы в Ruby on Rails'.

1
сказал 05.11.2006 в 4.21

[...] In this short story author describes how to implement file upload without full page reloading (technique used in gmail) with Ruby on Rails.read more | digg story Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages. [...]

2
Gomes
сказал 06.11.2006 в 12.04

Классная статья, спору нет. Созрел только небольшой вопросик как отследить загрузился ли файл на сервер, ведь существует куча преград при загрузке (размер файла превышает разрешенный и т.п.). Отдавать с сервера страницу с JavaScript, который бы дернул функцию на странице как то не красиво (да и не всегда сработает), а как узнать кроссбраузерно что пришло в теле страницы с сервера для меня загадка, если не сложно прошу расширения статьи.

3
сказал 20.11.2006 в 17.04

Попробуем применить на практике. Еще было бы интересно состыковать эту штуку с плагином upload_progress

4
сказал 20.11.2006 в 17.10

Ага, были такие мысли, займусь на досуге.

5
сказал 20.11.2006 в 21.30

[...] There is no way to upload files using AJAX. How Gmail does it then? Well, the answer is using <iframe>. Here is a post that describe this technique in detail. Infact we at Vinayak Solutions are using this technique from months, obviously inspired by Gmail. ;-) [...]

6
Anton Kirsanov
сказал 23.11.2006 в 10.35

Добавлю только, что для проверки статуса достаточно запустить интервалом в секунду калбэк функцию (я о javascript говорю), которая будет смотреть readyState у окна в скрытом фрейме.

7
сказал 23.11.2006 в 13.44

По поводу прогресса загрузки файла, посмотрите статью Юрия Рашковского RubyOnRails: AJAX File Upload Hint.

8
сказал 23.11.2006 в 18.44

Спасибо, погляжу

9
Maximark
сказал 23.11.2006 в 18.58

По поводу загрузки файлов без обновления, напоминаю прекрасную библиотеку dklab.ru
http://dklab.ru/lib/JsHttpRequest/

Версия 4.0

я уже писал как то про неё, но эффекта было ноль. И вот… получите и спокойно пользуйтесь. На сегодня я думаю это самое лучшее реализация технологии AJAX. И тем паче загрузки файлов без перезагрузки страницы !!!
Это не реклама… я сам давно пользуюсь и не я её писал.

10
сказал 01.12.2006 в 9.36

[...] There is no way to upload files using AJAX. How Gmail does it then? Well, the answer is using <iframe>. Here is a post that describe this technique in detail. Infact we are using this technique from months, obviously inspired by Gmail. [...]

11
сказал 04.01.2007 в 2.46

great article! its a tricky problem but your solution works like a charm ;-)

12
Rails Developer
сказал 29.01.2007 в 21.00

Thanks for the help but from the Apple site, %{style=”display: none”} doesn’t work on the iframe but if you set it to %{style=”height:0;width:0;border:0;”} then it will work.

13
сказал 12.02.2007 в 23.58

Hey, nice article.. I actually wrote a plugin that does this. I’m using it in a couple places, but had to write it so quickly that I wasn’t able to adequately test it on all platforms. You can check it out here: http://rubyforge.org/projects/remote-upload/

Please tell me what you think

14
сказал 14.02.2007 в 1.44

[...] Dmytro Shteflyuk’s Home » In-place file upload with Ruby on Rails (tags: ruby rubyonrails rails tutorial reference howto) [...]

15
John
сказал 16.02.2007 в 19.20

I’m using your code almost exactly and most of it seems to be working, but when i try to do something with the uploaded_file all it has is the filename, not the actual file data. Any ideas?

16
сказал 22.02.2007 в 1.09

Rails Developer, great thanks for the tip!

17
сказал 22.02.2007 в 1.20

Jeff, great news! Will check your plugin in short time. Thanks!

18
сказал 13.03.2007 в 19.17

Great article! Thanks! I’ve combined your solution with attachment_fu plugin and result is awesome! Thanks!

19
сказал 23.04.2007 в 11.37

Спасибо а идею реализации. Думаю что этой техникой можно пользотаться и в других случаях.

20
jeffguroo
сказал 11.12.2007 в 0.22

Seems as though the problem with the lack of data being transfered is a problem with Firefox. When I use ff the files are always empty, however when I use Exploder, the data is carried over.

21
jeffguroo
сказал 11.12.2007 в 0.24

this solution only seems to work on txt files. Formatting for PDFs and Word Docs were hosed.

22
jeffguroo
сказал 12.12.2007 в 0.26

Alright, that was because I was trying to do it with remote_form instead of a form_for. Only the text was making it through. BTW what was the name of the plugin that was used for returning js to the iframe? That link is dead.

23
jeffguroo
сказал 12.12.2007 в 2.46

The above mentioned plugin is: respondes_to_parent

24
сказал 12.12.2007 в 6.35

jeffguroo, you right
It’s impossible to upload file using AJAX’s XMLHttpRequest. So I have written this post to show how to do it using iframe.

Thanks for comment about broken link, I have fixed it.

25
jeffguroo
сказал 12.12.2007 в 7.34

after beeting my head against this all day, I have found that doing a simple

render :partial => "successful_attachment"

also works quite well in Rails v1.2.3 and the acts_as_attachment plugin. Thanks for the file upload/AJAX workaround… a lifesaver.

26
сказал 07.01.2008 в 4.08

All you really need is the first part. The form’s target=”IFrameName” is all that really matters.

As far as the IFrame. You can give it a width and height, and then any text that you generate in the php upload file will show there.

Really simple.

27
сказал 05.02.2008 в 16.45

Hi I have tried this in my app. In my app, I have a partial to display my form to upload files and in another partial i am listing the files uploaded. right now I have to redirect the page after uploading the files. But how display my file list partial initially and update it with adding the newly added file info every time i upload a new file…
any help appreciated

regards,
venkat

28
сказал 08.05.2008 в 13.35

[...] In-place file upload with Ruby on Rails - The GMail technique for asynchronous uploads. [...]

Оставить отзыв

Вы можете использовать простые теги форматирования HTML (вроде <a>, <ul> and others). Чтобы вставить пример код, используйте <code lang="php">$a = "hello";</code> (поддерживаемые языки: ruby, php, yaml, html, csharp, javascript). Также Вы можете использовать <code>$a = "hello";</code>, синтаксис не будет подсвечен. Если вы не хотите использовать тег <code>, замените символ < на &lt;.

Отправить

 
Copyright © 2005 - 2008, Dmytro Shteflyuk