Fonte:
Upload Assíncrono (iframe como AJAX) - 1 função simples - El Micox
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.
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
CODE
/* 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
var carregou = function() {
removeEvent( $m('micox-temp'),"load", carregou);
var cross = "java script: ";
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);
}
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
CODE
<script type="text/javascript" src="micoxUpload.js"></script>
3) Os parâmetros na hora de chamar a função são:
1. form - o form a ser submetido ou o ID de algum form que queira submeter.
2. url_action - url pra onde deve ser submetido o form. Tem a mesma função do parâmetro "action" de um form.
3. id_elemento_retorno - id do elemento que irá receber a informação de retorno.
4. html_exibe_carregando - Texto (ou imagem) que será exibido enquanto se carrega o upload
5. 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:
CODE
<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):
CODE
<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:
CODE
<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.
Comentários:
Ugo Stoso disse:
A página Login.asp
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
<META http-equiv="Content-Type" content="text/html;" charset="iso-8859-1">
<script src="js/micoxUpload.js" type="text/javascript"></script>
<script src="js/micoxAjax.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function Logar()
{ if(document.getElementById) { // Para os browsers complacentes com o DOM W3C.
var mensagem=document.getElementById('divMensagem');
var exibeResultado = document.getElementById('divMsg'); // div que exibirá a mensagem.
var login=document.getElementById('txtLogin');
var senha=document.getElementById('txtSenha');
//var CaminhoRetorno = 'include/Logar.asp?Login='+login.value+'&Senha='+senha.value;
//alert(CaminhoRetorno);return false;
var CaminhoRetorno = 'include/Logar.asp';
if(!login.value||!senha.value)
{ alert('Você deve informar seu login e senha corretamente,\ntodos os campos são de preenchimento\nobrigatório.');
login.focus;
return false;}
else if(senha.length<8)
{ alert('Senha menor que o mínimo permitido\nverifique se você está digitando a senha correta\ne tente novamente.');
senha.value='';
senha.focus;
return false;}
else
{ mensagem.style.position='absolute';
mensagem.style.left=0;
mensagem.style.top=0;
//mensagem.grow({to:{height:50,width:200}});
//mensagem.fadeIn();
mensagem.style.display='block';
//ajaxGet(CaminhoRetorno,exibeResultado,true);
micoxUpload('frmLogin',CaminhoRetorno,'divMsg','Carregando...','Erro ao carregar'); return false;
//return true;
}
}
}
</script>
</head>
<body id="body">
<form id="frmLogin" action="include/Logar.asp" method="post">
<div id="divLogar" style="Display:<%=divL%>;" class="Login">
<table border="0" cellpadding="2" cellspacing="0" class="conteudo">
<tr><td colspan="2" align="center" valign="top" class="TituloTela">Informe sua Conta.</td></tr>
<tr><td>Login:</td>
<td><input type="text" name="txtLogin" id="txtLogin" maxlength="20" /></td>
</tr>
<tr><td>Senha:</td>
<td><input type="password" name="txtSenha" id="txtSenha" maxlength="10" /></td>
</tr>
<tr><td colspan="2">
<input type="button" id="btnEntrar" value="Função" onclick="return Logar();" />
<input type="submit" name="subEntrar" id="subEntrar" value="Submit">
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
E a página logar.asp
Login = Request.QueryString.Item("login")
Senha = Request.QueryString.Item("senha")
teste1 = Request.Form.Item("txtLogin")
Senha = Request.Form.Item("txtSenha")
Response.Write (login&" === "&Senha&" ---- "&teste1&" +++ "&teste2)
Response.End%>
Onde estou errando?
Um grande abraço. Desde já agradecendo a atenção e krak, suas funções são muito maneiras.
Micox disse:
Acredito que o problema esteja aí.
(Você está usando o Firefox pra exibir os erros de javascript ou té testando no IEca? )
Ugo Stoso disse:
Acredito que o problema esteja aí.
(Você está usando o Firefox pra exibir os erros de javascript ou té testando no IEca? )
É q eu alterei várias vezes e devo ter me esquecido, estou usando o FireFox com o debug, mesmo com essa div o problema continua, essa div fica dentro da divMensagem.
Micox disse:
Ah, e faz o seguinte também: testa submeter o form sem usar minha função, pois pode ser que o erro esteja no ASP.
Ver o restante dos comentários no fórum (e aproveitar pra comentar também !).