W3docs

JavaScript FormData

Aprenda a API FormData do JavaScript: crie objetos FormData, leia e modifique campos com get, append, set e delete, envie dados e arquivos com fetch.

Lidar com dados de formulários de forma eficiente é essencial para criar páginas web dinâmicas e interativas. O JavaScript fornece a API FormData exatamente para isso: ela permite coletar os campos de um formulário, construir conjuntos de chave/valor programaticamente e enviá-los a um servidor — incluindo arquivos. Este guia aborda o que é FormData, como criá-lo e lê-lo, todos os métodos que ele expõe, como enviá-lo com fetch e os problemas mais comuns.

Entendendo o FormData

FormData é um objeto JavaScript nativo que representa um conjunto de pares chave/valor, modelado na forma como um navegador envia um formulário HTML. Ele simplifica a coleta de informações de formulários HTML e o envio assíncrono dessas informações a um servidor com a Fetch API.

Por que usá-lo em vez de construir um object simples?

  • Ele lê os campos de um formulário existente automaticamente — sem extração manual de value por input.
  • Ele suporta arquivos e Blobs, que objects simples e JSON não conseguem transportar.
  • Quando passado ao fetch, o navegador define o Content-Type correto (multipart/form-data) com o boundary certo por você.

Criando Objetos FormData

Crie um objeto FormData com o construtor FormData(). Se você passar um elemento <form>, todos os campos nomeados e habilitados daquele formulário são capturados de imediato. Você pode inspecionar o conteúdo iterando o método entries(), que retorna um iterador de pares [key, value]:

<script>
  function onSubmit(event) {
    event.preventDefault();
    const form = document.getElementById('myForm');
    const formData = new FormData(form);
    let results = '';
    for (const [key, value] of formData.entries()) {
      results += `${key}: ${value}\n`;
    }
    alert(results)
  }
</script>
<form id="myForm" onsubmit="onSubmit(event)">
  <input type="text" name="username" value="John Doe" />
  <input type="email" name="email" value="[email protected]" />
  <input type="submit" />
</form>

Acessando Dados do Formulário

Leia um único campo com get(), ou itere por todos os campos com entries() como mostrado acima. get() retorna o primeiro valor para uma chave (ou null se não existir):

<form id="myForm" onsubmit="onSubmit(event)">
  <input type="text" name="username" value="John Doe" />
  <input type="email" name="email" value="[email protected]" />
  <input type="submit" />
</form>
<script>
  function onSubmit(event) {
    const form = document.getElementById('myForm');
    const formData = new FormData(form);
    const username = formData.get('username');
    const email = formData.get('email');
    alert(`username: ${username}; email: ${email}`);
  }
</script>

Métodos do FormData

Além de ler um formulário existente, o FormData permite construir e modificar o conjunto de dados manualmente. Os seguintes métodos estão disponíveis em cada instância:

MétodoO que faz
append(name, value)Adiciona um novo valor. Se a chave já existir, mantém o valor antigo e adiciona outro, portanto uma chave pode ter múltiplos valores.
set(name, value)Define o valor para uma chave, substituindo todos os valores existentes para essa chave.
get(name)Retorna o primeiro valor para a chave, ou null.
getAll(name)Retorna um array de todos os valores para a chave.
has(name)Retorna true se a chave existir.
delete(name)Remove todos os valores para a chave.
entries() / keys() / values()Iteradores sobre os pares, chaves ou valores.

A diferença entre append e set é a fonte mais comum de bugs:

const fd = new FormData();
fd.append('tag', 'js');
fd.append('tag', 'web');   // append keeps both
console.log(fd.getAll('tag'));   // [ 'js', 'web' ]

fd.set('tag', 'html');     // set replaces all
console.log(fd.getAll('tag'));   // [ 'html' ]

console.log(fd.has('tag'));      // true
fd.delete('tag');
console.log(fd.has('tag'));      // false

Você também pode construir um FormData inteiramente em código — sem nenhum formulário — anexando campos diretamente. Um terceiro argumento para append/set define o nome do arquivo quando o valor é um Blob ou File.

Enviando FormData com a Fetch API

Um caso de uso comum para FormData é enviar dados de formulário ao servidor de forma assíncrona. Passe a instância FormData como o body de uma requisição fetch — o navegador define automaticamente o Content-Type como multipart/form-data com o boundary correto, portanto não defina esse cabeçalho você mesmo:

<form id="myForm" onsubmit="onSubmit(event)">
  <input type="text" name="title" value="A title" />
  <input type="text" name="body" value="A body" />
  <input type="submit" value="Submit Post" />
</form>
<div>post id: <span id="response"></span></div>
<script>
  function onSubmit(event) {
    event.preventDefault();
    const form = document.getElementById('myForm');
    const formData = new FormData(form);
    const responseSpan = document.getElementById('response');
    fetch('https://jsonplaceholder.typicode.com/posts', {
        method: 'POST',
        body: formData
    })
      .then(response => response.json())
      .then(data => { responseSpan.innerHTML = data.id; })
      .catch(error => console.error('Error:', error));
  }
</script>
Aviso

Quando você passa seu formulário ao construtor FormData, ele inclui automaticamente todos os campos do formulário HTML, inclusive os campos ocultos. Isso pode levar a comportamentos inesperados se você não tomar cuidado, especialmente se houver campos sensíveis ou desnecessários no formulário.

Lidando com Upload de Arquivos

FormData é a maneira padrão de fazer upload de arquivos, pois produz uma requisição multipart/form-data capaz de transportar conteúdo binário junto com campos de texto. Quando você constrói o FormData a partir de um formulário que contém um input <input type="file">, o arquivo selecionado já está incluído — não é necessário ler input.files e anexá-lo novamente:

<form id="fileUploadForm">
    <input type="file" name="file" />
    <input type="submit" value="Upload" />
</form>
<script>
    const form = document.getElementById('fileUploadForm');
    form.addEventListener('submit', (event) => {
        event.preventDefault();
        // The file input is captured automatically from the form.
        const formData = new FormData(form);
        fetch('https://httpbin.org/post', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => console.log('Upload successful:', data))
        .catch(error => console.error('Error:', error));
    });
</script>

Para anexar um arquivo que não faz parte de um formulário — por exemplo, um selecionado programaticamente — adicione-o explicitamente, opcionalmente fornecendo um nome de arquivo:

const formData = new FormData();
formData.append('avatar', fileObject, 'profile.png');

FormData vs. URLSearchParams

Ambos envolvem pares chave/valor, mas serializam de maneiras diferentes. Use FormData quando precisar enviar arquivos ou multipart/form-data. Use URLSearchParams quando tiver apenas texto e quiser um body compacto application/x-www-form-urlencoded (ou uma query string). Você pode até construir um a partir do outro quando todos os valores são strings:

const fd = new FormData();
fd.append('q', 'cats');
fd.append('page', '2');

const params = new URLSearchParams(fd);
console.log(params.toString());   // q=cats&page=2

Conclusão

FormData é uma ferramenta versátil e poderosa para gerenciar dados de formulários em aplicações JavaScript. Seja para lidar com inputs de texto simples ou uploads de arquivos complexos, FormData simplifica o processo e fornece uma interface conveniente para interagir com os dados do formulário. Ao dominar o FormData, você pode aprimorar a interatividade e a responsividade das suas aplicações web, proporcionando uma experiência de usuário fluida.

Praticar

Prática
Qual é um benefício de usar o objeto FormData em JavaScript?
Qual é um benefício de usar o objeto FormData em JavaScript?
Was this page helpful?