Olá povo, conforme prometido, tô postando aqui uma função pra você fazer upload bem parecido com ajax (não é ajax!!). Função simples e fácil de usar.
Ela faz um upload assíncrono, ou seja, não recarrega a página toda (assim como o AJAX).
Quem usa alguns serviços do google como o GMail ou o GooglePages já conhece este recurso muito bem.
Editado 14/01/09: Já há uma nova versão disponível.
Veja em valeus.net/micox/micoxUpload2.htm (ainda não está muito bem testada).
Upload usando apenas AJAX não é viável no ambiente da Internet pois, por motivos de segurança, os navegadores por padrão não dão acesso ao sistema de arquivos para o JavaScript (se quiser descobrir como ativar esta característica não padrão, leia aqui, mas acredito não ser muito útil ajax upload dessa forma).
Esta minha função utiliza técnicas que envolvem iframes, mas não vou dar explicações aqui não. Explicações sobre como desenvolvi a função serão dadas em um novo post. Este post aqui é só para o código.
Ah, sim, no próximo post mostrarei também uma função um pouco mais customizável já pra quem entende melhor de JavaScript.
Testado no Firefox 2.0, Internet Explorer 6.0 e Opera 9.1. Pelamordedeus, quem puder testar em outros navegadores aí e quiser citar a experiência, faça este favor à humanidade e cite a experiência nos comentários. Obrigado.
1) Coloque o código abaixo em um arquivo chamado micoxUpload.js
/* funçõezinhas padrão pra facilitar */ function $m(quem){ //apelido só pra não ficar repetindo o document.getElementById return document.getElementById(quem) } function remove(quem){ quem.parentNode.removeChild(quem); } function addEvent(obj, evType, fn){ //o velho do elcio.com.br/crossbrowser if (obj.addEventListener) obj.addEventListener(evType, fn, true) if (obj.attachEvent) obj.attachEvent("on"+evType, fn) } function removeEvent( obj, type, fn ) { if ( obj.detachEvent ) { obj.detachEvent( 'on'+type, fn ); } else { obj.removeEventListener( type, fn, false ); } } /* a que faz o serviço pesado */ function micoxUpload(form,url_action,id_elemento_retorno,html_exibe_carregando,html_erro_http){ /****** * micoxUpload - Submete um form para um iframe oculto e pega o resultado. Consequentemente pode * ser usado pra fazer upload de arquivos de forma assíncrona. * Use a vontade mas coloque meu nome nos créditos. Licença Creative Commons. * Versão: 1.0 - 03/03/2007 - Testado no FF2.0 IE6.0 e OP9.1 * Autor: Micox - Náiron JCG - elmicox.blogspot.com - micoxjcg@yahoo.com.br * Parametros: * form - o form a ser submetido ou seu ID * url_action - url pra onde deve ser submetido o form * id_elemento_retorno - id do elemento que irá receber a informação de retorno * html_exibe_carregando - Texto (ou imagem) que será exibido enquanto se carrega o upload * html_erro_http - texto (ou imagem) que será exibido se der erro HTTP. *******/ //testando se passou o ID ou o objeto mesmo form = typeof(form)=="string"?$m(form):form; var erro=""; if(form==null || typeof(form)=="undefined"){ erro += "O form passado no 1o parâmetro não existe na página.\n";} else if(form.nodeName!="FORM"){ erro += "O form passado no 1o parâmetro da função não é um form.\n";} if($m(id_elemento_retorno)==null){ erro += "O elemento passado no 3o parâmetro não existe na página.\n";} if(erro.length>0) { alert("Erro ao chamar a função micoxUpload:\n" + erro); return; } //criando o iframe var iframe = document.createElement("iframe"); iframe.setAttribute("id","micox-temp"); iframe.setAttribute("name","micox-temp"); iframe.setAttribute("width","0"); iframe.setAttribute("height","0"); iframe.setAttribute("border","0"); iframe.setAttribute("style","width: 0; height: 0; border: none;"); /* Não usei display:none pra esconder o iframe pois tem uma lenda que diz que o NS6 ignora iframes que tenham o display:none */ //adicionando ao documento form.parentNode.appendChild(iframe); window.frames['micox-temp'].name="micox-temp"; //ie sucks //adicionando o evento ao carregar /**** antigo que não funcionava no chrome var carregou = function() { removeEvent( $m('micox-temp'),"load", carregou); var cross = "javascript: "; cross += "window.parent.$m('" + id_elemento_retorno + "').innerHTML = document.body.innerHTML; void(0); "; $m(id_elemento_retorno).innerHTML = html_erro_http; $m('micox-temp').src = cross; //deleta o iframe setTimeout(function(){ remove($m('micox-temp'))}, 250); } *********/ //funfando no chrome graças ao Jhone turra var iframeId = document.getElementById('micox-temp'); var carregou = function() { window.document.getElementById( id_element ).innerHTML = iframeId.contentDocument.body.innerHTML; } addEvent( $m('micox-temp'),"load", carregou) //setando propriedades do form form.setAttribute("target","micox-temp"); form.setAttribute("action",url_action); form.setAttribute("method","post"); form.setAttribute("enctype","multipart/form-data"); form.setAttribute("encoding","multipart/form-data"); //submetendo form.submit(); //se for pra exibir alguma imagem ou texto enquanto carrega if(html_exibe_carregando.length > 0){ $m(id_elemento_retorno ).innerHTML = html_exibe_carregando; } }
2) Inclua (chame) este arquivo no seu HTML
<script type="text/javascript" src="micoxUpload.js"></script>
3) Os parâmetros na hora de chamar a função são:
- form - o form a ser submetido ou o ID de algum form que queira submeter.
- url_action - url pra onde deve ser submetido o form. Tem a mesma função do parâmetro "action" de um form.
- id_elemento_retorno - id do elemento que irá receber a informação de retorno.
- html_exibe_carregando - Texto (ou imagem) que será exibido enquanto se carrega o upload
- html_erro_http - Texto (ou imagem) que será exibido se der erro HTTP.
4) Pronto. Agora você várias formas de ativar o upload assíncrono. Vou exemplificar aqui 3 formas dentre as várias possíveis:
4.1) Uso básico. Você chama o upload a partir de um button (ou um input-type-button) em um form qualquer:
<legend>Uso básico</legend> <form> <input type="file" name="nome_qualquer" /> <div id="recebe_up_basico" class="recebe"> </div> <button onClick="micoxUpload(this.form,'upa.php','recebe_up_basico','Carregando...','Erro ao carregar'); return false;" type="button">testa</button> </form> </fieldset>
4.2) Ativando o upload quando o campo file perde o foco (onblur):
<fieldset> <legend>Uso no blur do input</legend> <form> <input type="file" name="nome_qualquer" onblur="micoxUpload(this.form,'upa.php','recebe_up_onblur','Carregando...','Erro ao carregar')" /> <div id="recebe_up_onblur" class="recebe"> </div> </form> </fieldset>
4.3) Agora uma forma que deixará seu form/upload acessível mesmo que o javascript esteja desabilitado:
<fieldset> <legend>Uso não intrusivo</legend> <form action="upa.php" target="_blank"> <input type="file" name="nome_qualquer" onblur="micoxUpload(this.form,'upa.php','recebe_up_3','Carregando...','Erro ao carregar')" /> <div id="recebe_up_3" class="recebe"> </div> </form> </fieldset>
Pronto. Customize aí agora e bora "uploadar". Bugs, erros, comenta ae.
Por favor, DÚVIDAS SOMENTE NO FÓRUM !!
No próximo post, a explicação e uma versão mais customizável pra quem já entende de JavaScript.
Gostou da dica acima? Então clica nos botões de compartilhamento abaixo e me ajude a dica a subir no Google.
Uhum pelo código Micox, vai me ser muito útil. veleu
ResponderExcluirDemais!!
ResponderExcluirVou testar e falo como funcionou.
Será que era só eu que tava louco por isso?
Obrigado.
Cara... valew!!! (apesar de eu não ter entendido algumas partes.. hehe)
ResponderExcluirhttp://forum.ievolution.com.br/index.php?showtopic=9372
dah 1 olhada lah... ok?
Opa, vamos testar. Belo trabalho.
ResponderExcluirOpa, beleza galera.
ResponderExcluirNo próximo post a explicação pra que vocês possam adaptar melhor.
E não se esqueçam de testar em diversos navegadores e me informar aqui, ok?
Muito bom esse código mas estou com um problema está dando um erro de objeto esperado, provavelmente na linha do input.
ResponderExcluirFala Micox, muito bom. O assunto é atualíssimo.
ResponderExcluirCara, me interessou o seu exemplo 3 - preocupado com acessibilidade, mas... precisaríamos de um botão submit, para ser acessível... não? sem JS e sem submit, resta apenas o [ENTER], que é desconhecido da maioria.
Que tal algo assim (só tem submit se não houver JS):
criamos o botão submit com o id "sbmt", normal, visível. Então...
window.onload = function() {
$m('sbmt').style.display = 'none';
}
Abraço, Cau
É verdade Cau.
ResponderExcluirEu lembrei só do acessível para o JavaScript e esqueci do outro tipo de acessibilidade. VAleus.
PARABENS BIXO
ResponderExcluirPor favor da pra tu pasar o teu msn pra mim usa o email pra mandar pedroafsouza@gmail.com
Email enviado pedro.
ResponderExcluirParabéns pelo código Micox.
ResponderExcluirMe vai ser muito util em cadastro de fotos de um sistema de concessionaria que estava parado justamente pq não conceguia um sistema de upload leval e funcional.
Seguem com seus direitos, nada de remove-los, certo?
Um grande abraço
Só uma dúvida: como é que o PHP deve tratar o dado recebido? Eu fiz o seguinte teste: submeti uma imagem jpeg para o script abaixo:
ResponderExcluirheader("Content-type: image/jpeg");
echo ($HTTP_RAW_POST_DATA);
O que ele retornou foi simplesmente a própria URL.
O PHP vai trabalhar exatamente do mesmo jeito que um upload normal.
ResponderExcluirAfinal, é isto mesmo que eu faço: só faço um upload via iframe.
Eu, por exemplo, uso um script de upload básico normal que se acha aí pela net.
Simplesmente excelente! Esta era uma solução que eu estava buscando há muito tempo e o autor expôs de forma simplificada. É ótimo saber que existem pessoas que não têm medo de compartilhar o conhecimento. Este tipo de iniciativa é sempre bem vinda.
ResponderExcluirParabéns e Obrigado!
Esse script é totalmente ÚTIL!
ResponderExcluirPerfeito..
Estou terminando um pequeno sistema para os alunos postarem notas de aula via web, assim que terminar te envio o Código Fonte .. e é claro vou por seus créditos nele.. Acredito em Software Livre!
Grande abraço.
Tem como disponibilizar o arquivo upa.php ?? Gostaria de testar..
ResponderExcluirOutra pergunta tem como validar por exemplo somente para fazer upload de imagens (jpg e gif) ?
Renato
Renato, é um script de upload como outro qualquer, pode ser PHP, ASP ou qualquer linguagem server-side.
ResponderExcluirEu por exemplo, no arquivo upa.php uso este script aqui: http://www.plugmasters.com.br/sys/materias/493/1/Upload-de-Imagens-Com-Seguran%E7a
Meu...show!!
ResponderExcluirMuito bom, parabéns.
ResponderExcluirExcelente trabalho. Sua dica funionou muito bem para mim.
ResponderExcluirusei hoje no meu site, muito bom parabens
ResponderExcluirlegal, mas não haveria necessidade de um javascript desse tamanho, poderia ser beeeeeeeeeem mais simples...
ResponderExcluirÉ, to sabendo manezei. Mas já tem uma versão 2.0 prontinha aqui na minha máquina só esperando eu blogar. hehe
ResponderExcluirÉ que tô querendo fazer uns exemplos mais reais e mais fáceis de usar.
Valeus...
Cara ..... você é um NINJA !!!
ResponderExcluirParabéns ... função utilíssima
Para ficar ultra completo só faltava o arquivo php :o)
ResponderExcluirBem,
ResponderExcluirtentei aceder ao forum, mas sem sucesso. Ja agora aproveito para colocar a minha duvida aqui:
Utilizando isto (sim, consegui, ate integrando com um plugin de Jquery para upload, fico lindinho...), como consigo saber se o upload terminou?
Cara, com essa função aí não dá pra saber não. com essa aí você apenas joga o resultado em uma div qualquer.
ResponderExcluirEsta semana pretendo postar uma versão nova desse upload aí onde será possível saber. Quem tiver pressa me mande um email que eu mando o código.
Galera, a função php pra upload, vocês acham no google pesquisando por Upload php. Simples!
Muito boa a função, fiquei de cara, vc esta de parabens.
ResponderExcluirEstou com um problema, testei no IE6 e da a mensagem de erro que é enviada por parametro para sua função.
ResponderExcluirPoderia me ajudar?
Meu email: tiagowanke@gmail.com
Agradeço desde já.
Fala Micox blz !?
ResponderExcluirEu percebi que pode se fazer um multiplo upload, porem, como eu poderia fazer uma verificação nos campos antes de enviar os arquivos ?
email: lfrs_web@yahoo.com.br
Vlw...
ps:belissimo codigo ^^
Ué.
ResponderExcluirÉ só chamar seu código (ou função) que faz a verificação ANTES de chamar minha função. Simples.
(supondo que você JÁ tenha uma função pra verificação)
Micox, só dizer uma coisa: Show de bola!! Simples de usar, de entender, direto ao ponto!! Muiito bom mesmo! Matou a pau!
ResponderExcluirAbraço!
obrigado por ajudar os reles mortais!!
ResponderExcluirMuito legal micox, me ajudou muito!
ResponderExcluirtambém não tive sucesso com o fórum
e lendo os posts percebi que você ja possui uma nova função de upload melhor que esta ja postada.
Gostaria de saber se esta ja esta pronta e queria analisa-la para ver qual se enquadra mais às minha necessidades.
Se puder me enviar esta outra no meu e-mail agradeço: eric_freitas@hotmail.com
------------------
dúvida sobre a função:
O resultado retornado na div/span é o retorno do meu PHP?
->Pq como vou usar com ajax, preciso do endereço da foto para enviar pro banco...
Muito Obrigado.
Att. Eric Rodrigo de Freitas
Parabéns! Funcionou beleza! Com firefox 3. Valeu!
ResponderExcluirei Micox, parabens pelo topico.
ResponderExcluirquase 1 ano e meio depois esse topico me ajudou.
Parabens pela iniciativa
Mano blz teu esquema funciona certinho so to com um problema não sei se é falta de entendimento do negocio mais quando eu envio o upload e ele esta dentro de um form para envio de outros campos depois de enviar o up o action do meu form para que muda e fica como o action do upload não sei se fui muito claro mais ai esta meu email ok se puder entrar em contato
ResponderExcluiremail/msn: a2web@a2web.com.br
Excelente seu artigo! não tive problemas em implementar na minha aplicação! Parabéns! Nota 1000!!!!
ResponderExcluirEste comentário foi removido pelo autor.
ResponderExcluirMto bom msmo, mas naum consegui colocar uma imagem no codigo...
ResponderExcluirex: micoxUpload(this.form,'cad_foto.php','recebe_up_basico',
'espera.gif','Erro ao carregar'); return false;"...
ele exibe somente o texto "espera.gif", a imagem está no mesmo diretorio do html.
Ué Rafa, é só colocar a tag img inteira ué.
ResponderExcluirGostei, to tentando usar, só queria saber onde está a versão 2.0?
ResponderExcluirMesmo assim agradeço
Olá! Sou Aline Amaral Rigues e vim agradecer a sua contribuição para nós programadores com o código apresentado! Agradeço veemente!
ResponderExcluirUm grande abraço!
Noh cara vlw d+,vou usar elas !
ResponderExcluirflwss abrass
Eh possivel aplicar esse codigo, usando Jquery?!
ResponderExcluirSim, é possível usar com jquery, mas acredito que o jquery tem seus próprios plugins para isso.
ResponderExcluirUma versão mais atualizada também pode ser vista aqui: http://webly.com.br/Micox/micoxUpload2.htm
Este comentário foi removido pelo autor.
ResponderExcluirShow de bola ... teria como me enviar a versao nova no email juniorpcosta@gmail.com ... obrigado....
ResponderExcluirOnde tem o script para dowload?
ResponderExcluirÉ uma gambi de primeira, porém resolve o problema.
ResponderExcluirO próprio Google usa o "upload em ajax" dessa forma.
Parabéns o/
Boa noite, preciso de uma ajuda sua ja mexi re-mexi nesse seu script, voce ja deve ter notado que quando clica para upar o nome do arquivo que ta sendo upado desaparece do box, precisava deixar o nome mostrando ate a finalizacao do up
ResponderExcluiralbert@volix.com.br
Oi aqui deu tudo certo, porém ja tentei varios arquivos para encaixar ai no upa.php e com nenhum eu obtive sucesso, será que não poderia incluir ele ai e deixar o tutorial ate mesmo mais completo?
ResponderExcluirNo meu caso preciso desse php para fazer upload de qualquer tipo de arquivo mesmo.
Primeiramente, eu gostaria de dar parabens pelo trabalho. Ficou fantástico, funcionou perfeitamente. Segundo, eu gostaria de saber se posso utiliza-lo em minha página comercial? Estou trabalhando em um site com alguns recursos AJAX e este seu código me serviu muito bem. Mas tenho preocupação de utiliza-lo de forma comercial.
ResponderExcluirPode sim Gilberto, sem problemas.
ResponderExcluirCodigo muito util, nao consegui compreender ele muito bem porem ele esta me ajudando na concepção do meu tcc na parte de cadastro, muito obrigado [creditos foram mantidos]
ResponderExcluirBoa tarde.. muito legal esse seu post. mas eu sou cru em programação de javascript e não entendi direito.. estou tentando criar uma mensagem de carregando o arquivo para os meus usuário não acharem q o arquivo não está carregando.. irei colocar sem problemas o seu nome no arquivo. uso linux e sou fã de GLP. se vc puder me ajudar eu agradeço.
ResponderExcluirO código não funciona para usuarios do CHROME e SAFARI. O problema está na função remove. Sendo mais específico, não é possivel tranformar o iframe em objeto, retornando NULL. Ambos os browsers não pegam o conteúdo do iframe com o getElementById nem com nenhuma outra função.
ResponderExcluirUmmm que saco.
ResponderExcluirValeu o aviso koto.
Atualmente ando meio sem tempo de corrigir a função mas tá aí o aviso.
Valeu.
Fiz uma mudança no código e ele agora também funciona no CHROME e SAFARI.
ResponderExcluirSubstitui:
var carregou = function() {
removeEvent( $m('micox-temp'),"load", carregou);
var cross = "javascript: ";
cross += "window.parent.$m('" + id_elemento_retorno + "').innerHTML = document.body.innerHTML; void(0); ";
$m(id_elemento_retorno).innerHTML = html_erro_http;
$m('micox-temp').src = cross;
//deleta o iframe
setTimeout(function(){ remove($m('micox-temp'))}, 250);
}
por:
var carregou = function() {
window.document.getElementById( id_elemento_retorno ).innerHTML = 'Arquivo enviado com sucesso';
}
Dessa forma ele a mensagem de retorno vai normalmente.
Vale Koto, vou alterar lá.
ExcluirOpa achei bem legal essa função, mais estou tendo problemas com o chrome e safari elea aparece carregando depois fica em branco, agora com essa alteração ele aparece o 'Arquivo enviado com sucesso'. Detalhe nas duas formas a imagem não é gravada
ResponderExcluirEu Também estava com problema com o CHROME quando fazia upload, a função só ficava carregando ou iria para uma página de erro do CHROME, a partir da dica do koto eu conseguir solucionar, em meu caso substituir por um código do jquery para recarregar.
ResponderExcluirexemplo:
Substituir a função para está:
var carregou = function() {
$.get(url_action, { id:'' },
function(data) {
$(seu_id_elemento_retorno).html(data);
return false;
});
}
ta ai a solução
ResponderExcluirvar iframeId = document.getElementById('micox-temp');
var carregou = function() {
window.document.getElementById( id_element ).innerHTML = iframeId.contentDocument.body.innerHTML;
}
Valeu Jhone
ExcluirVou alterar lá.