Utiliser les objets FormData

L'objet FormData vous permet de créer un ensemble de paires clef-valeur pour un envoi via XMLHttpRequest. Cet objet est destiné avant tout à l'envoi de données de formulaire, mais il peut être utilisé indépendamment des formulaires afin de transmettre des données associées à une clef. Les données transmises sont dans le même format qu'utiliserait la méthode submit() pour envoyer des données si le type d'encodage du formulaire correspondait à "multipart/form-data".

Créer un objet FormData de zéro

Vous pouvez créer un objet FormData en l'instanciant puis en lui ajoutant des champs au moyen de la méthode append(), comme ci-dessous :

var formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456); // le nombre 123456 est immédiatement converti en la chaîne "123456"

// Choix de l'utilisateur à partir d'un input HTML de type file...
formData.append("userfile", fileInputElement.files[0]);

// Pseudo-objet fichier JavaScript...
var content = '<a id="a"><b id="b">hey!</b></a>'; // le corps du nouveau fichier...
var blob = new Blob([content], { type: "text/xml"});

formData.append("webmasterfile", blob);

var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);
Remarque : les champs "userfile" et "webmasterfile" contiennent tous les deux un fichier. Le nombre assigné au champ "accountnum" est immédiatement converti en une chaîne de caractères par la méthode FormData.append()  (la valeur du champ peut être soit un Blob, soit un File, ou encore une chaîne de caractères : si la valeur n'est ni un objet Blob ni un objet File, la valeur est convertie en une chaîne de caractères).

Cet exemple crée une instance de FormData contenant des valeurs pour les champs nommés "username", "accountnum", "userfile" et "webmasterfile", puis utilise la méthode send() de XMLHttpRequest pour envoyer les données du formulaire. Le champ "webmasterfile" est un Blob. Un objet Blob représente un pseudo-objet fichier de données brutes et immuables. Les Blobs représentent des données qui ne sont pas forcément dans un format natif de JavaScript. L'interface File est basée sur le Blob, héritant des fonctionnalités du blob et l'étendant afin de supporter les fichiers système de l'utilisateur. Afin de construire un Blob, vous pouvez invoquer le constructeur Blob.

Récupérer un objet FormData à partir d'un formulaire

Pour construire un objet FormData qui contient les données d'un <form> existant, il suffit de spécifier cet élément formulaire lors de la création de l'objet FormData :

var formData = new FormData(someFormElement);

Par exemple :

var formElement = document.getElementById("myFormElement");
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
request.send(new FormData(formElement));

Vous pouvez également ajouter des données additionnelles à l'objet FormData après l'avoir extrait d'un formulaire et avant son envoi, comme ceci :

var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
formData.append("serialnumber", serialNumber++);
request.send(formData);

Cela vous permet de compléter les données du formulaire avant de les envoyer, en incluant des informations additionnelles qui ne sont pas nécessairement accessibles à l'utilisateur dans le formulaire.

Envoyer des fichiers avec un objet FormData

Vous pouvez aussi envoyer des fichiers en utilisant FormData. Il suffit d'inclure un élément <input> de type "file" :

<form enctype="multipart/form-data" method="post" name="fileinfo">
  <label>Your email address:</label>
  <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
  <label>Custom file label:</label>
  <input type="text" name="filelabel" size="12" maxlength="32" /><br />
  <label>File to stash:</label>
  <input type="file" name="file" required />
  <input type="submit" value="Stash the file!" />
</form>
<div id="output"></div>

Vous pouvez ensuite l'envoyer en utilisant un code semblable à celui-ci :

var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function(ev) {

  var
    oOutput = document.getElementById("output"),
    oData = new FormData(document.forms.namedItem("fileinfo"));

  oData.append("CustomField", "This is some extra data");

  var oReq = new XMLHttpRequest();
  oReq.open("POST", "stash.php", true);
  oReq.onload = function(oEvent) {
    if (oReq.status == 200) {
      oOutput.innerHTML = "Uploaded!";
    } else {
      oOutput.innerHTML = "Error " + oReq.status + " occurred uploading your file.<br \/>";
    }
  };

  oReq.send(oData);
  ev.preventDefault();
}, false);

Remarque : si vous passez une référence au formulaire, la méthode spécifiée dans le formulaire sera utilisée en remplacement de celle précisée dans l'appel à open().

Remarque : Cet exemple redirige les données en sortie vers un script PHP sur le serveur, et gère les erreurs HTTP, quoique d'une manière peu élégante.

Vous pouvez aussi ajouter un File ou un  Blob directement à l'objet FormData, comme ceci :

data.append("myfile", myBlob, "filename.txt");

Lorsque la méthode append est utilisée, il est possible de renseigner le troisième paramètre optionnel pour passer un nom de fichier à l'en-tête Content-Disposition qui est envoyée au serveur. Si aucun nom de fichier n'est spécifié (ou si le paramètre n'est pas supporté,) le nom "blob" est utilisé.

Vous pouvez aussi utiliser FormData avec jQuery si vous configurez les bonnes options :

var fd = new FormData(document.getElementById("fileinfo"));
fd.append("CustomField", "This is some extra data");
$.ajax({
  url: "stash.php",
  type: "POST",
  data: fd,
  processData: false,  // indique à jQuery de ne pas traiter les données
  contentType: false   // indique à jQuery de ne pas configurer le contentType
});

Soumettre des formulaires et téléverser des fichiers via AJAX sans objets FormData

Si vous souhaitez savoir comment sérialiser et soumettre via AJAX un formulaire sans utiliser d'objets FormData, veuillez consulter ce paragraphe.

Voir aussi

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : pa.buisson, jean-pierre.gay
 Dernière mise à jour par : pa.buisson,