JavaScript FormData
Scopri l'API FormData di JavaScript: crea oggetti FormData, leggi e modifica campi con get, append, set e delete, invia dati e file con fetch e confrontala con URLSearchParams.
Gestire i dati dei moduli in modo efficiente è fondamentale per la creazione di pagine web dinamiche e interattive. JavaScript mette a disposizione la FormData API proprio per questo scopo: consente di raccogliere i campi di un modulo, costruire set di coppie chiave/valore in modo programmatico e inviarli a un server, inclusi i file. Questa guida illustra cos'è FormData, come creare e leggere un'istanza, tutti i metodi che espone, come inviarla con fetch e le insidie più comuni.
Comprendere FormData
FormData è un object JavaScript integrato che rappresenta un insieme di coppie chiave/valore, modellato sul modo in cui il browser invia un modulo HTML. Semplifica la raccolta delle informazioni dai moduli HTML e il loro invio asincrono a un server tramite la Fetch API.
Perché usarlo al posto di un object semplice?
- Legge automaticamente i campi di un modulo esistente — nessuna estrazione manuale del
valueper ogni input. - Supporta file e
Blob, che un object semplice e il JSON non possono trasportare. - Quando viene passato a
fetch, il browser imposta automaticamente ilContent-Typecorretto (multipart/form-data) con il boundary giusto.
Creare oggetti FormData
Crea un object FormData con il costruttore FormData(). Se passi un elemento <form>, ogni campo con nome e abilitato in quel modulo viene acquisito immediatamente. Puoi esaminare il contenuto iterando il metodo entries(), che restituisce un iteratore di coppie [chiave, valore]:
<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>Accedere ai dati del modulo
Leggi un singolo campo con get(), oppure itera su tutti i campi con entries() come mostrato in precedenza. get() restituisce il primo valore per una chiave (o null se non esiste):
<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>Metodi di FormData
Oltre alla lettura di un modulo esistente, FormData consente di costruire e modificare il set di dati manualmente. I seguenti metodi sono disponibili su ogni istanza:
| Metodo | Cosa fa |
|---|---|
append(name, value) | Aggiunge un nuovo valore. Se la chiave esiste già, mantiene il valore precedente e ne aggiunge un altro, quindi una chiave può avere più valori. |
set(name, value) | Imposta il valore per una chiave, sostituendo eventuali valori esistenti per quella chiave. |
get(name) | Restituisce il primo valore per la chiave, o null. |
getAll(name) | Restituisce un array di tutti i valori per la chiave. |
has(name) | Restituisce true se la chiave esiste. |
delete(name) | Rimuove tutti i valori per la chiave. |
entries() / keys() / values() | Iteratori sulle coppie, le chiavi o i valori. |
La differenza tra append e set è la fonte di bug più comune:
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È anche possibile costruire un FormData interamente nel codice — senza alcun modulo — aggiungendo i campi direttamente. Un terzo argomento per append/set imposta il nome del file quando il valore è un Blob o un File.
Inviare FormData con la Fetch API
Un caso d'uso comune per FormData è l'invio asincrono dei dati del modulo al server. Passa l'istanza FormData come body di una richiesta fetch — il browser imposta automaticamente il Content-Type a multipart/form-data con il boundary corretto, quindi non impostare quell'intestazione manualmente:
<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 passi il tuo modulo al costruttore FormData, vengono inclusi automaticamente tutti i campi del modulo HTML, compresi i campi nascosti. Questo può causare comportamenti inattesi se non si presta attenzione, soprattutto se nel modulo sono presenti campi sensibili o non necessari.
Gestire il caricamento di file
FormData è il metodo standard per caricare file, poiché produce una richiesta multipart/form-data in grado di trasportare contenuto binario insieme a campi di testo. Quando costruisci il FormData da un modulo che contiene un input <input type="file">, il file selezionato è già incluso — non è necessario leggere input.files e aggiungerlo di nuovo:
<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>Per allegare un file che non fa parte di un modulo — ad esempio uno selezionato in modo programmatico — aggiungilo esplicitamente, fornendo facoltativamente un nome file:
const formData = new FormData();
formData.append('avatar', fileObject, 'profile.png');FormData vs. URLSearchParams
Entrambi racchiudono coppie chiave/valore, ma si serializzano in modo diverso. Usa FormData quando devi inviare file o dati multipart/form-data. Usa URLSearchParams quando hai solo testo e vuoi un body compatto application/x-www-form-urlencoded (o una query string). Puoi persino costruire uno dall'altro quando ogni valore è una string:
const fd = new FormData();
fd.append('q', 'cats');
fd.append('page', '2');
const params = new URLSearchParams(fd);
console.log(params.toString()); // q=cats&page=2Conclusione
FormData è uno strumento versatile e potente per la gestione dei dati dei moduli nelle applicazioni JavaScript. Che si tratti di semplici input di testo o di caricamenti di file complessi, FormData semplifica il processo e fornisce un'interfaccia pratica per interagire con i dati dei moduli. Padroneggiando FormData, puoi migliorare l'interattività e la reattività delle tue applicazioni web, offrendo un'esperienza utente fluida.