Comment décoder une URL en JavaScript (guide complet)
JavaScript fournit decodeURIComponent() pour décoder des composants d'URI individuels et decodeURI() pour décoder des URI complètes. Utilisez try-catch pour gérer les URI mal formées. Les API URL et URLSearchParams offrent des alternatives plus sûres pour analyser les URL.
decodeURIComponent() — Décoder un composant d'URI
decodeURIComponent() est la fonction principale pour décoder les chaînes encodées en URL en JavaScript. Elle décode toutes les séquences percent-encoded, en les reconvertissant vers leurs caractères d'origine. Utilisez cette fonction pour décoder les valeurs de paramètres de requête, les segments de chemin ou tout composant unique d'une URI.
// Décodage de base
console.log(decodeURIComponent('hello%20world'));
// "hello world"
console.log(decodeURIComponent('price%3D10%26qty%3D2'));
// "price=10&qty=2"
// Décodage de caractères Unicode
console.log(decodeURIComponent('caf%C3%A9'));
// "cafe" (avec accent)
console.log(decodeURIComponent('%E4%B8%AD%E6%96%87'));
// Caractères chinois
// Décodage de la valeur d'un paramètre de requête depuis une URL
const url = 'https://example.com/search?q=C%2B%2B%20%26%20Java';
const params = url.split('?')[1];
const value = params.split('=')[1];
console.log(decodeURIComponent(value));
// "C++ & Java"
decodeURIComponent() décode toutes les séquences percent-encoded, y compris celles des caractères réservés comme %2F (/) et %3F (?). C'est le comportement correct lorsqu'on travaille sur des composants d'URI individuels, mais cela peut poser problème si on l'applique à une URL complète.
decodeURI() — Décoder une URI complète
decodeURI() décode une URI complète tout en préservant sa structure. Contrairement à decodeURIComponent(), elle ne décode pas les séquences qui représentent des caractères réservés d'URI comme %2F (/), %3F (?), %23 (#) et %26 (&).
// decodeURI préserve la structure de l'URI
console.log(decodeURI('https://example.com/my%20page?q=hello%20world'));
// "https://example.com/my page?q=hello world"
// Les espaces sont décodés, mais /, ? et = sont préservés
// Comparaison avec decodeURIComponent sur une URL complète
console.log(decodeURIComponent('https%3A%2F%2Fexample.com%2Fpath'));
// "https://example.com/path" - décode correctement si toute l'URL était encodée
// decodeURI ne décode pas les séquences de caractères réservés
console.log(decodeURI('path%2Fto%2Ffile'));
// "path%2Fto%2Ffile" - %2F n'est PAS décodé car / est réservé
console.log(decodeURIComponent('path%2Fto%2Ffile'));
// "path/to/file" - %2F EST décodé
Utilisez decodeURI() lorsque vous souhaitez rendre une URL plus lisible (à des fins d'affichage, par exemple) sans en altérer la structure. Pour la plupart des cas d'usage programmatiques, vous voudrez appliquer decodeURIComponent() à des composants individuels.
Gérer les URI mal formées
decodeURI() et decodeURIComponent() lèvent toutes deux une URIError lorsqu'elles rencontrent des séquences percent-encoded invalides. Cela se produit avec des signes pourcentage isolés, des séquences incomplètes ou des séquences d'octets UTF-8 invalides. Encadrez toujours les opérations de décodage dans un bloc try-catch lorsque vous manipulez des URL fournies par l'utilisateur ou provenant de sources externes.
// Ces appels lèvent URIError: URI malformed
try {
decodeURIComponent('%'); // pourcentage isolé
} catch (e) {
console.error(e.message); // "URI malformed"
}
try {
decodeURIComponent('%2'); // séquence incomplète
} catch (e) {
console.error(e.message); // "URI malformed"
}
// Fonction de décodage sécurisée
function safeDecode(str) {
try {
return decodeURIComponent(str);
} catch (e) {
console.warn('Failed to decode:', str);
return str; // retourne la chaîne d'origine en cas d'échec
}
}
// Corrige les séquences pourcentage mal formées avant le décodage
function fixAndDecode(str) {
// Remplace un % isolé par %25 (signe pourcentage encodé)
const fixed = str.replace(/%(?![0-9A-Fa-f]{2})/g, '%25');
return decodeURIComponent(fixed);
}
console.log(fixAndDecode('100% complete'));
// "100% complete"
Utiliser l'API URL (recommandé)
Les API modernes URL et URLSearchParams offrent une manière plus sûre et plus structurée d'analyser et de décoder les URL. Elles gèrent automatiquement l'encodage et le décodage, ce qui réduit le risque d'erreurs.
// Analyse une URL et accède à ses composants (décodés automatiquement)
const url = new URL('https://example.com/path%20here?q=hello%20world&lang=en');
console.log(url.pathname); // "/path here" (décodé)
console.log(url.search); // "?q=hello%20world&lang=en" (brut)
// URLSearchParams décode automatiquement les valeurs de paramètres
console.log(url.searchParams.get('q')); // "hello world"
console.log(url.searchParams.get('lang')); // "en"
// Parcours de tous les paramètres
for (const [key, value] of url.searchParams) {
console.log(key, '=', value);
}
// q = hello world
// lang = en
// URLSearchParams traite + comme un espace (encodage de formulaire)
const formParams = new URLSearchParams('q=hello+world&lang=en');
console.log(formParams.get('q')); // "hello world"
// Construction d'URL avec encodage automatique
const newUrl = new URL('https://example.com/search');
newUrl.searchParams.set('q', 'C++ & Java');
newUrl.searchParams.set('page', '1');
console.log(newUrl.toString());
// "https://example.com/search?q=C%2B%2B+%26+Java&page=1"
Erreurs de décodage courantes
Erreur 1 : décoder une URL complète avec decodeURIComponent(). Cela peut casser la structure de l'URL si elle contient des caractères réservés encodés. Un %2F dans une valeur de requête deviendrait un /, ce qui pourrait changer le sens de l'URL.
Erreur 2 : double décodage. Si une chaîne a déjà été décodée une fois, la décoder à nouveau peut produire des résultats inattendus ou des erreurs. Par exemple, la chaîne %2520 se décode d'abord en %20, puis en un espace. Si vous n'attendez qu'un seul niveau d'encodage, le double décodage corrompt les données.
// Problème de double décodage
const encoded = '%2520'; // Ceci est un %20 encodé
console.log(decodeURIComponent(encoded)); // "%20" (correct - un seul niveau)
console.log(decodeURIComponent(decodeURIComponent(encoded))); // " " (double décodage !)
// Vérifie si une chaîne doit être décodée avant de la décoder
function needsDecoding(str) {
return str !== decodeURIComponent(str);
}
Erreur 3 : ne pas gérer le signe +. decodeURIComponent() ne convertit pas le + en espace. Si vous décodez des données au format form-urlencoded, vous devez d'abord remplacer les + par des espaces, ou utiliser URLSearchParams qui gère cela automatiquement.
// decodeURIComponent ne décode PAS + comme un espace
console.log(decodeURIComponent('hello+world'));
// "hello+world" (et non "hello world" !)
// Solution : remplacer + avant le décodage
function decodeFormValue(str) {
return decodeURIComponent(str.replace(/\+/g, ' '));
}
console.log(decodeFormValue('hello+world'));
// "hello world"
// Ou utiliser URLSearchParams (gère + automatiquement)
const params = new URLSearchParams('q=hello+world');
console.log(params.get('q'));
// "hello world"