Gestion des URL d'objets en JavaScript : createObjectURL et revokeObjectURL

L'API URL de JavaScript fournit des mécanismes essentiels pour manipuler des références vers des objets locaux, notamment les blobs et les fichiers. Ces méthodes permettent de créer des adresses temporaires pour des données binaires sans avoir à les encoder en base64, optimisant ainsi les performances.

Génération d'une URL d'objet

La méthode URL.createObjectURL() génère une chaîne de caractères (DOMString) qui sert d'URL unique pointant vers l'objet fourni en paramètre. Cette URL n'est valide que dans le contexte du document qui l'a instanciée.

const urlObjet = URL.createObjectURL(cible);

Le paramètre cible doit être soit un objet File, soit un objet Blob :

  • Objet File : Représente un fichier utilisateur, généralement obtenu via un élément <input type="file"> ou une opération de glisser-déposer.
  • Objet Blob : Représente des données binaires brutes. Il peut être instancié manuellement via le constructeur new Blob() ou récupéré comme réponse d'une requête réseau lorsque le type de réponse est configuré appropriément.

Gestion de la mémoire et révocation

Chaque appel à createObjectURL allouee de la mémoire pour maintenir la référence vers l'objet, même si une URL a déjà été générée pour ce même fichier. Bien que le navigateur nettoie atuomatiquement ces références lors de la fermeture de l'onglet ou de la page, les applications web modernes (comme les SPA) nécessitent une gestion manuelle pour éviter les fuites de mémoire.

Pour libérer explicitement cette mémoire, on utilise URL.revokeObjectURL(). Cette méthode indique au navigateur que l'URL n'est plus nécessaire et qu'il peut détruire la référence.

URL.revokeObjectURL(urlObjet);

Une fois révoquée, l'URL ne peut plus être utilisée pour accéder à la ressource. C'est une pratique courante de révoquer l'URL immédiatement après le chargement complet de la ressource par le navigateur, par exemple dans l'événement onload d'une image.

Implémentation partique : Chargement binaire d'une image

Voici une implémentation moderne utilisant XMLHttpRequest pour récupérer une image sous forme de données binaires, l'afficher via une URL d'objet, puis libérer la mémoire.

<button id="btn-charger-image">Charger l'image binaire</button>
<div id="conteneur-image"></div>
document.getElementById('btn-charger-image').addEventListener('click', async () => {
    try {
        const donneesBlob = await recupererRessourceBinaire('ressource.png');
        const urlTemporaire = URL.createObjectURL(donneesBlob);

        const elementImg = document.createElement('img');
        elementImg.src = urlTemporaire;

        elementImg.onload = () => {
            // Libération de la mémoire une fois l'image rendue par le moteur
            URL.revokeObjectURL(urlTemporaire);
        };

        document.getElementById('conteneur-image').appendChild(elementImg);
    } catch (erreur) {
        console.error('Échec du chargement :', erreur);
    }
});

function recupererRessourceBinaire(chemin) {
    return new Promise((resoudre, rejeter) => {
        const requete = new XMLHttpRequest();
        requete.open('GET', chemin, true);
        
        // Configuration cruciale pour obtenir un Blob
        requete.responseType = 'blob';

        requete.onload = function() {
            if (requete.status >= 200 && requete.status < 300) {
                resoudre(requete.response);
            } else {
                rejeter(new Error(`Erreur HTTP: ${requete.status}`));
            }
        };

        requete.onerror = () => rejeter(new Error('Erreur réseau'));
        requete.send();
    });
}

Dans cette approche, la configuration de requete.responseType = 'blob' est déterminante. Elle indique au navigateur de traiter la réponse directement comme un objet binaire. Par conséquent, les données sont accessibles via la propriété requete.response. Tenter d'accéder à requete.responseText dans ce contexte renverra une erreur ou une valeur nulle, car le moteur a déjà converti le flux en objet Blob.

Étiquettes: JavaScript API URL BLOB file XMLHttpRequest

Publié le 15 octobre à 13h29