W3docs

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 value per 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 il Content-Type corretto (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:

MetodoCosa 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>
Attenzione

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=2

Conclusione

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.

Esercitazione

Pratica
Qual è un vantaggio dell'utilizzo dell'object FormData in JavaScript?
Qual è un vantaggio dell'utilizzo dell'object FormData in JavaScript?
Was this page helpful?