Upload de arquivos e dados com ajax

Ajax não envia arquivos.
Ajax não envia arquivos.

Isso sempre foi verdade até a chegada de algumas APIs JavaScript junto com o html5.

Ajax nada mais é do que uma requisição http feita pelo objeto XMLHttpRequest, e o retorno é devolvido diretamente ao javascript, assim não tendo o famoso e as vezes indesejado “refresh”.

Irei utilizar como base o código disponibilizado na MDN, no tutorial FormData. Esta serve apenas para enviar dados em formato: chave/valor, ou seja, os nossos inputs.

Código completo no github

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Upload ajax</title>
</head>
<body>

<form action="upload.php" method="post" id="upload">
  <input type="file" name="file" id="file" accept="image/*" />
  <input type="text" name="name" value="wBruno" />
  <input type="submit" value="Send!" />
</form>

<div id="preview"></div>

<script>
var $formUpload = document.getElementById('upload'),
    $preview = document.getElementById('preview'),
    i = 0;

$formUpload.addEventListener('submit', function(event){
  event.preventDefault();

  var xhr = new XMLHttpRequest();

  xhr.open("POST", $formUpload.getAttribute('action'));

  var formData = new FormData($formUpload);
  formData.append("i", i++);
  xhr.send(formData);

  xhr.addEventListener('readystatechange', function() {
    if (xhr.readyState === 4 && xhr.status == 200) {
      var json = JSON.parse(xhr.responseText);

      if (!json.error && json.status === 'ok') {
        $preview.innerHTML += '<br />Enviado!!';
      } else {
        $preview.innerHTML = 'Arquivo não enviado';
      }

    }
  });

  xhr.upload.addEventListener("progress", function(e) {
    if (e.lengthComputable) {
      var percentage = Math.round((e.loaded * 100) / e.total);
      $preview.innerHTML = String(percentage) + '%';
    }
  }, false);

  xhr.upload.addEventListener("load", function(e){
    $preview.innerHTML = String(100) + '%';
  }, false);

}, false);

</script>

</body>
</html>

5 Comments

  1. Oi… Belo artigo.

    Só não entendi a funcionalidade do seguinte comando:

    formData.append(“i”, i++);

  2. Pedro Soares

    junho 1, 2016 at 13:35

    E ai Bruno,

    Cara estou recorrendo a vc referente a uma dúvida que vem me perseguindo a muito tempo. Queria fazer upload de imagem via ajax, porém o querido jQuery não faz isso pra gente, uma pena.

    Pesquisei em diversos lugares e encontrei o ajaxForm. Se vc souber manipula-lo tem como me passar um breve tutorial me mostrando o:
    – html simples de como fazer
    – a parte do js, se possível usando jQuery
    – a parte de PHP porem só recebendo o arquivo FILE o restante eu ja tenho feito.

    Só preciso mesmo enviar o file para o php de forma dinâmica

    OBS: É sinceramente uma dúvida muito chatinha que ando tendo,se puder me ajudar cara ficarei muito grato. Agradeço desde já a vc

  3. Silvio Santos

    julho 12, 2016 at 19:05

    Legal…
    Para upload, eu uso o Uploadify e/ou UploadiFive.
    Funcionam muito bem, inclusive com arquivos simultâneos.

  4. Oi Bruno, estou recorrendo a você pelo seguinte:

    Tenho uma Datatable de gestão de produtos onde coloquei um botão para editar cada um dos produtos, botão esse que abre uma modal bootstrap com o formulário respectivo. Esse formulário tem os dados do produto e uma imagem. Como posso fazer para enviar dados e ficheiros no mesmo submit via Ajax? Como recebo esses mesmos dados no PHP $_post e $_files vindos numa mesma requisição Ajax. E ainda, o que me aconselha a usar para fazer CROP/UPLOAD dessa imagem e escrever na BD.

    Obrigadão

Deixe uma resposta

Your email address will not be published.

*