Upload AJAX
Eae pessoal, hoje irei mostrar como fazer um upload simples simulando AJAX.
Quem quiser conferir como ficará o exemplo, segue o link.
E no fim do post, tem um zip com o exemplo funcionando.
Vamos lá!
Primeiro: AJAX significa Asynchronous JavaScript and XML, e consiste na idéia de se comunicar com um servidor web, sem a necessidade de recarregar a página.
Segundo: O objeto XMLHttpRequest é um objeto JavaScript que torna possível essa comunicação assíncrona.
Terceiro: O XMLHttpRequest não suporta o envio de formulário com enctype="multipart/form-data", que são utlizados para envios de arquivo. Isso ocorre porque dessa maneira os caracteres não são codificados, não permitindo assim o seu envio pelo objeto.
Então como faremos ?
Simples!
Iremos simular um upload com AJAX, utilizando um iframe.
Essa técnica é bastante utilizada, e não é complicada de se fazer.
Bom, agora que ja temos uma breve explicação, vamos ao código!
Primeiro o nosso código HTML, com o formulário para upload.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>UPLOAD</title> <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script> </head> <body> <h1>Escolha o arquivo</h1> <div style="display: none;" id="loader_img"> <img src="img/loader.gif" alt="Carregando..." title="Carregando..." /> </div> <div style="display: none;" id="upload_msg"></div> <form action="do_upload.php" id="form_upload" enctype="multipart/form-data" method="post" target="upload_target"> <p> <label>Arquivo <input type="file" name="arquivo" id="arquivo" /> </label> </p> <p> <input type="submit" name="do_action" id="do_action" value="Upload" /> </p> </form> <iframe id="upload_target" name="upload_target" src="#"></iframe> </body> </html>
Excplicação
- Incluimos a jQuery no nosso documento pois iremos utilizá-la, caso voce não conheca a jQuery, neste post falo um pouco sobre ela, e apresento alguns seletores básicos.
- Note que temos duas divs com
display:none, adiv#loader_imgé mostrada quando o form sofrer um submit, e adiv#upload_msgé utilizada para mostrar mensagens para o usuário. - O form possui um target apontando para o iframe, aqui esta a mágica! Como esta apontando para o iframe, isso indica que o formulário será processado dentro do iframe, evitando que a página seja recarregada.
Agora vamos ao nosso código JavaScript dessa página.
<script type="text/javascript">
$(document).ready(function() {
$('#upload_target').hide();
$('form#form_upload').submit(function() {
$('#upload_msg').hide(500);
$(this).hide(500, function() {
$('#loader_img').show(500);
});
});
});
</script>
Explicação
- Linha 3, escondemos o iframe da página, pois não queremos que ele sejá visto.
- Linha 5, selecionamos o form, e colocamos uma função de callback para quando o form sofrer o submit.
- Linha 6, escondemos a div de mostrar mensagens para o usuário. Eu sei ela já esta com
display:none, mas se ja foi feito um upload, ela estará visível. - Linha 7, Escondemos o form, e na função de callback mostramos a imagem de carregando.
O nosso código da página ficou assim
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>UPLOAD</title>
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#upload_target').hide();
$('form#form_upload').submit(function() {
$('#upload_msg').hide(500);
$(this).hide(500, function() {
$('#loader_img').show(500);
});
});
});
</script>
</head>
<body>
<h1>Escolha o arquivo</h1>
<div style="display: none;" id="loader_img">
<img src="img/loader.gif" alt="Carregando..." title="Carregando..." />
</div>
<div style="display: none;" id="upload_msg"></div>
<form action="do_upload.php" id="form_upload" enctype="multipart/form-data" method="post" target="upload_target">
<p>
<label>Arquivo
<input type="file" name="arquivo" id="arquivo" />
</label>
</p>
<p>
<input type="submit" name="do_action" id="do_action" value="Upload" />
</p>
</form>
<iframe id="upload_target" name="upload_target" src="#"></iframe>
</body>
</html>
Bom, agora falta a página de action do form, do_upload.php nela fazemos o upload e escrevos o status do upload na página, além de escondermos a div com a imagem de carregando e mostramos novamente o form.
Vamos lá
<?php
/******* CONFIGURACOES *******/
// Nome do input FILE
$inputFile = 'arquivo';
// Limitar extensoes (TRUE ou FALSE)
$limitarExt = TRUE;
// Extensoes validas
$extensoesValidas = array('.gif', '.jpg', '.jpeg', '.png', '.txt');
// Limitar tamanho (TRUE ou FALSE)
$limitarTamanho = FALSE;
// Tamanho em bytes
$tamanhoMax = 1024 * 200;
// Caminho do upload
$caminho = 'upload/';
// Sobrescrever arquivo (TRUE ou FALSE)
$sobrescrever = FALSE;
/******* FIM CONFIGURACOES *******/
$nomeArquivo = $_FILES[$inputFile]['name'];
$tamanhoArquivo = $_FILES[$inputFile]['size'];
$nomeTempArquivo = $_FILES[$inputFile]['tmp_name'];
$erroArquivo = $_FILES[$inputFile]['error'];
$extArquivo = strtolower(strrchr($nomeArquivo, '.'));
$msg = '';
if ( $erroArquivo == 4 ) {
// Nenhum arquivo enviado
$msg = 'Selecione um arquivo!';
} elseif ( $erroArquivo == 0 ) {
// Verifica a extensao
if ( ($limitarExt === TRUE) && (! in_array($extArquivo, $extensoesValidas)) ) {
$msg = 'Tipo de arquivo inválido!';
// Verifica o tamanho
} elseif ( ($limitarTamanho === TRUE) && ($tamanhoArquivo > $tamanhoMax) ) {
$msg = 'Arquivo muito grande!';
// Varifica se o arquivo ja existe
} elseif ( ($sobrescrever === FALSE) && (file_exists($caminho . $nomeArquivo)) ) {
$msg = 'Arquivo já existe!';
} else {
// Se moveu o arquivo
if ( move_uploaded_file($nomeTempArquivo, $caminho . $nomeArquivo) ) {
$msg = 'Arquivo enviado com sucesso!';
} else {
$msg = 'Ocorreu um erro durante o envio do arquivo, tente novamente.';
}
}
} else {
$msg = 'Ocorreu um erro durante o envio do arquivo, tente novamente.';
}
sleep(1);
$out = <<<OUT
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
$('#loader_img', top.document).hide();
$('#upload_msg', top.document).html('$msg');
$('#upload_msg', top.document).show()
$('form#form_upload p label input:file', top.document).remove();
$('form#form_upload label', top.document).append('<input type="file" name="arquivo" id="arquivo" />');
$('form#form_upload', top.document).show();
</script>
OUT;
echo $out;
?>
Desenvolvi um script de upload bem completo, que voce pode usar inclusive em outros sistemas que voce esteja desenvolvendo.
Explicação
Primeiro possuimos a parte de configurações, onde voce pode configurar:
- O nome do input file que voce esta usando no form.
- Se deve-se limitar extensões para envio de arquivo.
- As extensões válidas.
- Se deve-se limitar o tamanho do arquivo enviado.
- O tamanho máximo permitido.
- O caminho do upload.
- Se deve-se sobrescrever o arquivo, caso ela já exista.
Não irei explicar linha por linha, pois os comentários no código ja são auto explicativos.
O script só vai até a linha 58, após isso, são realizadas operações para escrever o JavaScript que irá manipular a página, como dito anteriormente.
Linha 60, adicionei a função sleep() para caso o arquivo enviado seja muito pequeno, ou não tenha sido enviado nenhuma arquivo, haja tempo necessário para os efeitos esconderem os elementos na página.
Linha 62, começamos a preparar o JavaScript para manipular a página.
Note que utilizamos os seletores dentro de top.document. Ou seja, serão selecionados elementos no documento acima do iframe, que é justamente a página.
No JavaScript
- Linha 66, escondemos a imagem de carregando.
- Linha 67, escrevemos o retorno do upload, variável $msg.
- Linha 68, mostramos a div#upload_msg.
- Linha 69, removemos o input file do form, pois o atributo value de um input file, não pode ser modificado.
- Linha 70, inserimos um novo input file.
- Linha 71, mostramos o form.
E pronto!
A idéia de funcionamento é bem simples, é selecionado o arquivo, faz o upload que é processado no iframe, e o PHP escreve o JavaScript que manipula a página.
Dica: Se voce tem o FireBug, após um upload verá que dentro do iframe, foi escrito aquele código JavaScript.
Download
Caso haja alguma dúvida, poste nos comentários.
Aprendi muito
Olá Jennifer, fico mto feliz que tenha gostado!
ola muito bom adorei,
eu estava procurando um desses e acabei achando aq, obrigado
estou tentando implementar em meu script, mais sempre que eu aperdo o botão para enviar fica mostrando a imagem de carregamento e nunca carrega
vc poderia me ajudar ?
dê um olhada no codigo.
http://paste-it.net/public/r609950/
t+
ola thiago Rigo
tão simples, srsrr deu certo aq obrigado
vlw pelo post maravilhoso
t+
Que bom que deu certo, não tive tempo de responder atarde…
Mas se tiver alguma dúvia é só falar
olá Thiago Rigo, tudo bem? Parabens pelo codigo.. facil e bem explicado…
só preciso de um detalhe…
como posso executar uma funcao ao carregar a imagem no iframe?
no meu caso, seria para atualizar a lista de produtos assim que for enviado a imagem…
estou tentando assim…
$(document).ready(function() {
$(top.document).MostraProdutos(”);
// MostraProdutos é uma funcao que esta na pagina pai
});
agradeço se poder ajudar..
obrigado
Oi Maicon!
Primeiro obrigado, tente usar
window.parent.MostraProdutos('');Abs
@Thiago Rigo
Olá bom dia amigo… obrigado Thiago, foi de grande ajuda…
consegui tambem chamando ONLOAD no IFRAME..
ou seja, quando carregar o iframe ele dispara o evento.. pra mim funcionou… valew