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.
Olá, hoje darei início a uma série de artigos explicando e exemplificando o seletor da jQuery.