UPLOAD com AJAX é possível?
Primeiro vamos tentar definir o que é e o que não é AJAX.
O Asynchronous Javascript And XML é uma metodologia para fazer requisições ao servidor sem a necessidade de recarregar novamente a página. Junte a isso umas artimanhas com XML e um punhado de código e você terá um sistema web que se parece aos sistemas desktop.
Quem faz essa grande maravilha é o todo poderoso JavaScript, que envia uma cabeçalho HTTP para o servidor, recepciona sua resposta e nos permite trabalhar com essas novas informações no corpo da página já carregada. Isso é AJAX.
Através do JavaScript você pode preparar essa requisição HTTP com variáveis ou não, em POST ou GET, com variáveis dos formulário ou do próprio código JavaScript, etc... Mas o grande problema é para enviar arquivos!
Para enviar arquivos, é necessário que o JavaScript leia todo o arquivo e envie na requisição HTTP, e isso até que é possível, mas a maioria dos browser negam o acesso do JavaScript aos arquivos por questões de segurança(veja isso: http://www.mozilla.org/projects/security/components/jssec.html). Vejam nesse link (http://www.captain.at/ajax-file-upload.php) o melhor método de fazer o upload com AJAX que eu já vi, porém é necessário mexer nas configurações de segurança do Mozilla e é claro que não temos como pedir para que os usuários façam isso nos seus navegadores. :(
Mas aí você pode está pensando: "Mas eu já vi upload com AJAX! Isso é possível!", "O Gmail faz Upload com AJAX então é possível!", etc...
Então vamos para a realidade nua e crua!
O que o Gmail faz e que a maioria das pessoas fazem para dar a impressão de Upload com AJAX é um método muito simples. Eles criam o Iframe sem bordas, com largura igual a zero, de modo que o Iframe não seja visível. Depois submetem normalmente (sem AJAX) o formulário que envia o arquivo com o Iframe como destino, depois eles capturam o conteúdo do IFrame para uma variável do JavaScript e daí por diante trabalham como trabalhariam caso fosse uma requisição com AJAX.
Moral da história: a página não é descarregada, você vê apenas o resultado e (se o programdor for esperto) nem o iframe aparece no código. :D
Mas, no final das contas, isso é AJAX?
Para mim, a resposta é não.
A requisição não é assícrona, já que a página é carregada pelo navegador, apesar do usuário não ver.
Vejam alguns links de programadores que fizeram isso (conscientemente):
http://www.air4web.com/files/upload/
http://elmicoxcodes.blogspot.com/2007/03/asynchronous-upload-like-ajax-1.html
Eu sinceramente espero que alguém consiga me provar o contrário, e mostre aqui uma forma de utilizar apenas (eu disse APENAS) AJAX para enviar o arquivo. Está lançado o desafio! Ficarei feliz em postar aqui mesmo os créditos de quem achar a solução.
Abraços.
Links patrocinados
Últimos artigos do editor
Destaques
Layouts Free
Confira a nossa coletânea de layouts prontos para uso. Diversas categorias para você escolher.
Caro Jota Brasil, Na verdade a única decepção que você pode ter me causado é por não ter compartilhado conosco a sua solução, pois este espaço não é destinado a gurus nem donos da verdade. Leia novamente o post para entender a proposta do artigo. Abraços
Publicado em: 29/04/2008 - 17:01
decepcionou os professores de português, isso sim...
Publicado em: 29/04/2008 - 16:39
Fiz um upload em ajax e com barra de progressão!!! t desepsionei!!! kkkkkkkk
Publicado em: 19/03/2008 - 18:41
Willian, Muito bom exemplo, porém eu citei esse método no terceiro parágrafo. Inclusive eu o considero a melhor forma de se tentar fazer isso. Mas como eu havia dito, dessa forma "é necessário mexer nas configurações de segurança do Mozilla e é claro que não temos como pedir para que os usuários façam isso nos seus navegadores.". Caso você consiga utilizar esse método sem a necessidade do usuário alterar as configurações avançadas do browser dele então isso será possível. :-)
Publicado em: 24/01/2008 - 19:28
Obrigado por ler e partiicar do Oficina da Net. Veja bem que no estágio The AJAX File Upload Component Renderer O autor explica: " In Stage 1, we need to render the HTML file upload tag and the button that will be responsible for starting off this process. Once the user clicks the upload button, the form is submitted through an IFRAME ( to prevent blocking on the page) and the second stage of the process is initiated. Below is an extract of the rendering code :" Ele cria um IFrame e envia o post do arquivo para ele. Esse exemplo eu citei no artigo, teaóricamente não é AJAX, primeiro pq não é o JavaScript que envia, mas sim a página HTML normalmente para outra 'janela'. Além disse nao é assíncrono, pq o conteúdo do Iframe, neste caso vazio, é carregado e descarregado como em qq página. Ainda estamos procurando essa solução, se encontrar, nos avise!
Publicado em: 07/08/2007 - 10:00
Estava procurando no google e encontrei este http://today.java.net/pub/a/today/2006/02/09/file-uploads-with-ajax-and-jsf.html T+
Publicado em: 03/08/2007 - 22:41
Willian, Muito bom exemplo, porém eu citei esse método no terceiro parágrafo. Inclusive eu o considero a melhor forma de se tentar fazer isso. Mas como eu havia dito, dessa forma \"é necessário mexer nas configurações de segurança do Mozilla e é claro que não temos como pedir para que os usuários façam isso nos seus navegadores.\". Caso você consiga utilizar esse método sem a necessidade do usuário alterar as configurações avançadas do browser dele então isso será possível.
Publicado em: 05/07/2007 - 13:54
<html> <body> <script> var url = "post.php"; var binary; var filename; var mytext; function upload() { filename = document.getElementById('myfile').value; mytext = document.getElementById('mytext').value; document.getElementById('ajaxbutton').disabled = true; // request local file read permission try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch (e) { alert("Permission to read file was denied."); } // open the local file var file = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile); file.initWithPath( filename ); stream = Components.classes["@mozilla.org/network/file-input-stream;1"] .createInstance(Components.interfaces.nsIFileInputStream); stream.init(file, 0x01, 00004, null); var bstream = Components.classes["@mozilla.org/network/buffered-input-stream;1"] .getService(); bstream.QueryInterface(Components.interfaces.nsIBufferedInputStream); bstream.init(stream, 1000); bstream.QueryInterface(Components.interfaces.nsIInputStream); binary = Components.classes["@mozilla.org/binaryinputstream;1"] .createInstance(Components.interfaces.nsIBinaryInputStream); binary.setInputStream (stream); // start AJAX file upload in 1 second window.setTimeout("ajax_upload()", 1000); } function ajax_upload() { // request more permissions try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch (e) { alert("Permission to read file was denied."); } http_request = false; http_request = new XMLHttpRequest(); if (!http_request) { alert('Cannot create XMLHTTP instance'); return false; } // prepare the MIME POST data var boundaryString = 'capitano'; var boundary = '--' + boundaryString; var requestbody = boundary + '\n' + 'Content-Disposition: form-data; name="mytext"' + '\n' + '\n' + mytext + '\n' + '\n' + boundary + '\n' + 'Content-Disposition: form-data; name="myfile"; filename="' + filename + '"' + '\n' + 'Content-Type: application/octet-stream' + '\n' + '\n' + escape(binary.readBytes(binary.available())) + '\n' + boundary; document.getElementById('sizespan').innerHTML = "requestbody.length=" + requestbody.length; // do the AJAX request http_request.onreadystatechange = requestdone; http_request.open('POST', url, true); http_request.setRequestHeader("Content-type", "multipart/form-data; \ boundary=\"" + boundaryString + "\""); http_request.setRequestHeader("Connection", "close"); http_request.setRequestHeader("Content-length", requestbody.length); http_request.send(requestbody); } function requestdone() { if (http_request.readyState == 4) { if (http_request.status == 200) { result = http_request.responseText; document.getElementById('myspan').innerHTML = result; } else { alert('There was a problem with the request.'); } document.getElementById('ajaxbutton').disabled = false; } } </script> <form> Text: <input type="text" id="mytext" name="mytext" size="40"> <br> File: <input type="file" id="myfile" name="datafile" size="40"><br> <input type="button" id="ajaxbutton" value="AJAX IT" onclick="upload();"> </form> <div id="sizespan"></div> <hr> <div id="myspan"></div> </body> </html>
Publicado em: 21/06/2007 - 15:09