Strict Standards: Non-static method themeGluedIdeas_Subtle::initOptions() should not be called statically in /home/riopro/www/blog.riopro.com.br/wp-content/themes/gluedideas_subtle/header.php on line 19
Riopro Blog - » Simulando chamadas Ajax para upload de arquivos

Simulando chamadas Ajax para upload de arquivos



Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Esse artigo vai mostrar como fazer upload de imagens e arquivos de forma assíncrona. A solução apresentada não será nada que não venha sendo usado a pelo menos 4 anos, mas acho que vale a explicação. Na primeira parte, a explicação será mais ampla, independente de linguagem. Em seguida, trataremos só de Rails, usando o plugin responds_to_parent.

Você usa o Gmail? Se usa já deve ter visto a forma assíncrona de envio de arquivos. Nada de mandar fazer o upload. Selecione o arquivo e pronto, o upload comece a ser feito, sendo depois substituído por um link. Acompanhe nas imagens abaixo:

gmail_upload.png

gmail upload feito

Aparentemente nada de mais, afinal, Ajax  já está há tempos na nossa vida. Correto? Bom, infelizmente, incorreto! Isso porque XMLHttpRequest não faz envio de arquivos. Um dos motivos vem do fato do Javascript ser executado em um sandbox isolado dos arquivos do seu computador por questões de segurança.

Para contornar essa restrição, existem, basicamente, dois modelos:

1) o primeiro é usando o Flash (se gosta disso, veja no final o link sobre o swfupload). Essa forma é prática, mas eu, pessoalmente, sou totalmente contra. Acho o Flash algo muito intrusivo e inútil em aplicações mobile. E agora, com o HTML5 e as tags de vídeo e áudio incorporadas ao browser, para mim ele tende a morrer. Morrer é forte, mas seguramente perder muito espaço;

2) A segunda forma é a usada no Gmail e em várias outras aplicações espalhadas na internet. É a submissão do formulário para um target que é na verdade, um iframe oculto na própria página. É sobre isso esse artigo.

Para isso, mudamos nosso formulário normal para submeter para um target.

<form target=’frame_upload’ enctype=’multipart/form-data’ id=’form_upload’ method=’post’ action=’/image’>
<input id=’photo’ name=’photo’ size=’30′ type=’file’>
<input value=’Upload »’ type=’submit’>
</form>
<iframe id=’frame_upload’ style=’width:1px;height:1px;border:0px’></iframe>

UPDATE: antes eu havia escrito que era para usar style display:none. Porém, esse artigo  me fez mudar de idéia ao falar que alguns browsers podem ignorar o iframe e enviar o arquivo para uma nova página por conta do display:none.

A página será submetida como uma ação post normal. A diferença é que o resultado atualizará apenas o iframe que aqui chamamos de frame_upload. E aí vem o golpe de mestre, o retorno deverá ser um html contendo um script. Esse script deve conter uma chamada para avaliar a resposta em um window.parent. Window.parent nesse caso será a página que contém o iframe. Fazendo, com isso, que a chamada se pareça com uma chamada Ajax normal.

Como exemplo, vejamos como é a resposta que o plugin responds_to_parent gera no Rails:


<html><body>
<script type='text/javascript' charset='utf-8'>
var loc = document.location;
with(window.parent) { setTimeout(function() { window.eval(’#{SCRIPT_A_SER_EXECUTADO}’); loc.replace(’about:blank’); }, 1) }
</script>
</body>
</html>

Onde SCRIPT_A_SER_EXECUTADO é o que vai, no final das contas alterar a página pai. Simples e genial.

Fazendo o upload usando o Rails e o plugin responds_to_parent

NOTA: Para que a explicação não deixe dúvidas, criei uma aplicação de exemplo no GitHub, é só ver no link abaixo:

http://github.com/riopro/iframe/tree/master

Como implementar em RoR? Para isso, vamos usar o plugin responds_to_parent. Ele é simples e não altera a sua resposta rjs normal. O primeiro passo é baixar o plugin em:

http://code.google.com/p/responds-to-parent/downloads/list

e descompactá-lo na pasta vendor/plugins da sua aplicação. Na resposta da sua action, você simplesmente aninha a resposta dentro de uma chamada responds_to_parent, dessa forma:

responds_to_parent do

render :update do |page|
page.replace_html(’image_upload’, :partial => ‘image_upload’, :locals => {:image => @image})
end
end

Nesse caso, a minha resposta vai substituir o div com id image_upload com a resposta. Sendo que o div image_upload deve existir na página que contém o iframe.  Espero que seja útil essa dica.

Links úteis complementares:

http://github.com/otaviofcs/iframe/tree/master

http://kpumuk.info/ruby-on-rails/in-place-file-upload-with-ruby-on-rails/

http://sean.treadway.info/responds-to-parent/

http://khamsouk…ajax-file-uploads-in-rails-…and-responds_to_parent

http://malsup.com/jquery/form/

http://swfupload.org/

Informações e Links

Junte-se comentando, lendo o que os outros dizem ou colocando um link a partir do seu blog.


Outros Artigos

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
Enviando imagens para S3 assincronamente em Rails

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
Tornando o Firefox 3.5 o seu browser padrão no Ubuntu 9.04

Comente

Tire um tempo para comentar e nos dizer o que você acha. Alguns códigos HTML são permitidos para formatação.

Comentários dos Leitores


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

[…] Uma aplicação de exemplo foi criada usando Rails e o plugin livre responds_to_parent, mas a explicação inicial vale para qualquer linguagem.” [referência: blog.riopro.com.br] […]


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Excelente artigo camarada. Simples e mostra tudo que se precisa.


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

obrigado. Espero que tenha sido útil…


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

[…] Simulando chamadas Ajax para upload de arquivos Hits para esta publicação: 1 […]


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Interessante.

Edluise Costa
http://www.ecadti.com.br/


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Eu realmente queria enviar uma pequena palavra para agradecer a você para os pontos fantásticos que você está escrevendo sobre blog.riopro.com.br. Minha pesquisa de internet demorado tem no final foi homenageado com idéias extremamente bom para trocar com os meus amigos. I ‘d expressar que muitos dos visitantes nos sites realmente são extremamente dotados de existir em uma comunidade notável com tantos indivíduos encantador com pontos úteis. Eu me sinto muito feliz por ter usado sua página e olhar para a frente a tantos momentos mais divertidos de ler aqui. Muito obrigado novamente por um monte de coisas.


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Eu realmente planejada para discutir o seu blog é incrivelmente realista. Opto por ouvir algo totalmente novo com essa conta de que eu realmente fornecer o site idêntico ao meu Unidos estados durante este assunto assim que esta ajuda específica? Abundância todos s. Eu era capaz de uma boa olhada sobre o assunto, mais notado um número tão grande de blogs, mas em contraste com isso. Obrigado por revelar tanto dentro blog.riopro.com.br


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Faz uma grande falta o ajax fazer upload de arquivos de forma nativa. Ótimo artigo.