attention, les ex-L3 n'ont pas eu le cours de web service et donc CORS
expliquer intérêt des typedarray en pratique. les typedarray ne sont qu'une vue sur le arraybuffer.
formdata: on peut hériter d'un formulaire existant. ???
regarder les new tricks in XHR2 (et les docs de MDN) dans les liens: ajouter ce qui est intéressant au cours
Manipuler des fichiers en JS
L'API « File » permet de manipuler depuis le navigateur des fichiers fournis
par l'utilisateur
On peut notamment les envoyer au serveur, mais aussi les modifier depuis le client
File et Blob
Le type Blob représente un tas de données (binaires)
on peut récupérer sa taille et son type MIME
pour le manipuler il faut utiliser d'autres outils
Le type File étend Blob en ajoutant le nom du fichier et la date de dernière modification
Construire un objet File ou Blob
Les widgets d'upload ont un attribut files qui contient une liste d'instances de File
correspondant aux fichiers sélectionnés par l'internaute
On peut récupérer un fichier sur le serveur en Ajax
valeur blob pour l'attribut responseType de XHR
On peut utiliser le constructeur de Blob (voir docs)
FileReader
Pour accéder au contenu d'un fichier (ou d'un blob), on peut utiliser un FileReader
Le FileReader permet de récupérer le contenu sous trois formes :
sous forme de chaîne de caractères, avec readAsText. Si l'encodage n'est pas UTF-8, il faut le spécifier.
sous forme de ArrayBuffer avec readAsArrayBuffer (voir plus loin)
sous forme de data-URL avec readAsDataURL (voir plus loin)
Attention, ces trois méthodes sont asynchrones : quand le travail est terminé, le FileReader renvoie l'événement load et le résultat est récupérable dans son attribut result.
ArrayBuffer
Un tableau d'octets… sauf qu'on ne peut pas accéder directement au contenu
Un TypedArray est une vue sur le tableau d'octets qui dépend de comment les octets doivent être interprétés : entiers signés ou non, flottants, 8 bits, 16 bits, 32 bits…
Exemple de création de Uint8Array : let toto = new Uint8Array(buffer);, avec buffer une instance de ArrayBuffer.
Data-URL
Une data-URL est une URL vers un fichier dont le contenu (binaire) est défini par l'URL elle-même
L'URL ne pointe donc pas vers un emplacement : elle contient elle-même le fichier vers lequel elle « pointe »
Le type MIME est optionnel (text/plain;charset=US-ASCII par défaut)
L'encodage est optionnel, on peut mettre directement le contenu si celui-ci est textuel (en remplaçant les caractères spéciaux via l'encodage URL). Si le contenu est binaire, on utilise la base 64.
Exemples :
l'URL précédente représente une image GIF
l'URL data:,coucou représente un fichier texte dont le contenu est « coucou ».
l'URL data:text/html,<script>alert('hi');</script> représente un document HTML qui produit une alerte JS.
Les data-URL sont notamment utilisées pour embarquer de petites images (type icônes) directement dans du HTML
La méthode readAsDataURL du FileReader renvoie donc le fichier sous forme de data-URL. Ça peut être pratique pour des images, mais les data-URL deviennent vite très longues…
si besoin d'une URL vers le fichier, il est beaucoup plus adapté d'utiliser une blob-URL
Blob-URL
Pour récupérer le fichier manipulé en mémoire par JS, on peut utiliser une blob URL
window.URL.createObjectURL(mon_blob) : renvoie une URL ressemblant à blob:https://ensweb.users.info.unicaen.fr/a5748e7f-4213-4adc-a134-a206af015299, la dernière partie étant un identifiant unique
Cette URL fait référence au blob en question. On peut l'utiliser pour télécharger le fichier (en faisant un lien vers l'URL) ou pour ajouter l'image dans la page (si le blob est une image)
mêmes utilisations que les data-URL donc, sauf que la longueur de l'URL est fixée (elle ne contient pas de données, mais un simple identifiant)
… cependant, une blob-URL n'est valable que tant que la page n'est pas fermée
Attention, les blob-URL prennent de la mémoire : si vous en créez plusieurs, libérez les précédents avec window.URL.revokeObjectURL(mon_url)
Si vous avez généré l'URL juste pour ajouter l'image à la page, vous pouvez la révoquer immédiatement après — la révocation ne supprime pas l'image.
POST en Ajax
XHR permet de faire des requêtes POST
Le corps de la requête est passé en paramètre à send()
On peut aussi envoyer un blob comme corps de la requête, mais il faut que le serveur sache quoi en faire (par défaut les serveurs attendent des POST formatés avec des formulaires)
Exemple : supposons que la page contienne un formulaire d'identifiant toto. Le code suivant le soumet via JS :
let formElement = document.getElementById('toto');
let formData = new FormData(formElement);
let xhr = new XMLHttpRequest();
xhr.open('POST', 'recup.php');
xhr.send(formData);
Soumettre le formulaire avec XHR permet notamment de suivre la transmission : XHR a un attribut upload qui reçoit régulièrement des événements progress
Ces événements indiquent la proportion du formulaire qui a déjà été reçue par le serveur — utile si le formulaire contient un ou plusieurs fichiers
Attention, il faut que le formulaire soit utilisable sans JS ! Pas question de rendre la page moins accessible juste pour ajouter une barre de progression…