Olá pessoal, tudo certo? Várias pessoas me perguntam como fazer upload de arquivos com ajax e hoje pretendo apresentar uma solução para isso. Na verdade, não se trata de um upload com ajax, mas sim um upload dinâmico, porém para um usuário comum isso é indiferente.

A solução é simples e conhecida: fazer um iframe contendo um campo do tipo file, fazemos o envio desse arquivo dentro do iframe e então com a ajuda do jQuery recuperamos as informações desse arquivo e trazemos para a página pai. Nesse artigo irei utilizar anexo de arquivos como exemplo.

Confira o resultado final

1. Upload (upload.php)

Inicialmente iremos fazer uma página que fará o upload de um arquivo, assim como é feito normalmente. Caso você tenha dúvidas, pode consultar esses dois artigos: Upload simples de imagem com PHP/MySQL e Upload de vários arquivos com PHP.

Bom pessoal, nesse arquivo será feito apenas um upload simples. Resumindo, quando enviado o formulário nós recuperamos as informações desse arquivo, verificamos se sua extensão é válida, caso seja, geramos um nome aleatório para esse arquivo e enviamos para o servidor.

Vamos agora criar nosso código javascript (utilizando jQuery), que será incluído no cabeçalho desse arquivo:

Talvez não faça tanto sentido agora, porém mais adiante você entenderá melhor, vamos aos detalhes:

  • Linha 3: Como esse arquivo ficará dentro de um iframe, precisamos saber quem é a página pai, para isso definimos uma variável com o documento da página pai;
  • Linha 5, 8: Aqui está um detalhe interessante. Como a linguagem servidor (PHP) é executada primeiro que a cliente (javascript), nós fazemos um teste. Se a variável erro foi definida, nós imprimimos um alert, que depois será executada pelo javascript, que exibirá uma mensagem de alerta com o erro que foi armazenado;
  • Linha 10: Caso não haja erro, e a variável nome foi definida, ou seja, o arquivo foi enviado;
  • Linha 13: Colocamos na lista (que será criada adiante) com ID igual a anexos um item, porém perceba que foi passado no segundo parâmetro do seletor a variável pai, portanto ele irá buscar o ul#anexos da página pai. Nesse item colocamos o nome aleatório do arquivo na propriedade LANG. Logo após, colocamos uma imagem que será responsável por remover o anexo, note que definimos, no evento onclick, a chamada da função removeAnexo(), está será explicada adiante.
  • Linha 18: Quando o usuário selecionar um arquivo.
  • Linha 20: Verificamos se um arquivo foi realmente selecionado.
  • Linha 23: Exibimos nosso loader (carregando).
  • Linha 25: Enviamos o formulário via javascript.

2. A página pai (index.php)

Está será a página principal, onde colocaremos o iframe que incluirá o nosso arquivo de upload:

Nessa estrutura, criamos a lista (ul#anexos) onde serão adicionados os anexos, logo abaixo criamos nosso iframe e chamamos nosso arquivo de upload (upload.php). A essa altura, nosso upload dinâmico já está “funcional”, porém precisamos criar a função para remover o anexo:

  • Linha 2: Criamos nossa função que receberá como parâmetro o elemento da imagem;
  • Linha 5: A imagem está dentro do item (li), certo? Portanto, através do método parent() selecionamos o item (li) e pegamos o valor da propriedade LANG (Lembra que colocamos o nome do arquivo aqui?);
  • Linha 7: Fazemos uma requisição ajax com nosso próprio arquivo, e passamos como ação ‘removeAnexo’ e também o nome do arquivo anexado. Isso será preciso para que possamos remover o arquivo do servidor;
  • Linha 9: Quando terminado a requisição, removemos o elemento li de nossa página.

Vamos então criar a função PHP (logo no inicio do arquivo) que removerá o arquivo do servidor:

Parece que agora acabou né? Ainda não. Como iremos recuperar esses anexos quando enviado o formulário? Já que nosso formulário está simplesmente assim:

A solução é criar campos ocultos com os nomes dos arquivos quando enviado o formulário, para isso:

  • Linha 3: Quando nosso formulário for enviado;
  • Linha 5: Procuramos cada item (li) em nossa lista de anexo e passamos por cada um através do laço each();
  • Linha 7: Recuperamos o nome (aleatório) do arquivo que foi armazenado na propriedade LANG;
  • Linha 9: Através do prepend() adicionamos um campo oculto (hidden) dentro de nosso formulário (#upload) e colocamos o nome do arquivo como valor. Note que atribuímos o nome como anexos[] para que assim possamos recuperar os anexos já dentro de um array com PHP.

Agora, para fins de teste você pode adicionar o seguinte no inicio do arquivo:

Assim, você pode perceber, que quando enviado o formulário, o nome de nossos arquivos ficaram no array anexos e então podemos armazená-los no banco de dados, por exemplo.

3. Finalizando

Bom pessoal, meu objetivo nesse artigo foi apresentar uma alternativa para “simular” um upload com ajax. Se você tiver outra alternativa, compartilhe conosco. Dúvidas ou críticas construtivas são sempre bem vindas.

Download dos arquivos

Espero que vocês tenham entendido, até a próxima.
Abraços.