Página Inicial > PHP, jQuery > Upload AJAX

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

  1. 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.
  2. Note que temos duas divs com display:none, a div#loader_img é mostrada quando o form sofrer um submit, e a div#upload_msg é utilizada para mostrar mensagens para o usuário.
  3. 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

  1. Linha 3, escondemos o iframe da página, pois não queremos que ele sejá visto.
  2. Linha 5, selecionamos o form, e colocamos uma função de callback para quando o form sofrer o submit.
  3. 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.
  4. 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:

  1. O nome do input file que voce esta usando no form.
  2. Se deve-se limitar extensões para envio de arquivo.
  3. As extensões válidas.
  4. Se deve-se limitar o tamanho do arquivo enviado.
  5. O tamanho máximo permitido.
  6. O caminho do upload.
  7. 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

  1. Linha 66, escondemos a imagem de carregando.
  2. Linha 67, escrevemos o retorno do upload, variável $msg.
  3. Linha 68, mostramos a div#upload_msg.
  4. Linha 69, removemos o input file do form, pois o atributo value de um input file, não pode ser modificado.
  5. Linha 70, inserimos um novo input file.
  6. 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.

Categories: PHP, jQuery Tags: , ,
  1. 26, outubro, 2009 em 01:10 | #1

    Aprendi muito

  2. 7, novembro, 2009 em 17:13 | #2

    Olá Jennifer, fico mto feliz que tenha gostado!

  3. 25, maio, 2010 em 03:08 | #3

    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+

  4. 25, maio, 2010 em 17:37 | #4

    ola thiago Rigo

    tão simples, srsrr deu certo aq obrigado

    vlw pelo post maravilhoso

    t+

  5. 25, maio, 2010 em 20:55 | #5

    Que bom que deu certo, não tive tempo de responder atarde…
    Mas se tiver alguma dúvia é só falar :)

  6. Maicon
    4, junho, 2010 em 19:11 | #6

    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

  7. 6, junho, 2010 em 15:43 | #7

    Oi Maicon!
    Primeiro obrigado, tente usar window.parent.MostraProdutos('');
    Abs

  8. Maicon
    7, junho, 2010 em 10:03 | #8

    @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

  1. Nenhum trackback ainda.

Spam Protection by WP-SpamFree