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
valuepor input. - Ele suporta arquivos e
Blobs, que objects simples e JSON não conseguem transportar. - Quando passado ao
fetch, o navegador define oContent-Typecorreto (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étodo | O 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')); // falseVocê 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>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=2Conclusã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.