Pourquoi l'URL encoding existe

Une URL semble être une simple chaîne de caractères, mais elle suit une grammaire stricte. Certains caractères ont une signification spéciale : ? sépare le chemin de la query string, & sépare les paramètres, = sépare une clé de sa valeur, # démarre un fragment, et / structure le chemin. Dès qu'une valeur utilisateur contient l'un de ces caractères, l'URL peut devenir ambiguë ou cassée.

L'URL encoding résout ce problème en transformant les caractères sensibles en séquences percent-encoded. Par exemple, un espace devient %20, é devient %C3%A9, et & devient %26. Le navigateur, le serveur ou l'API peut ensuite décoder la valeur sans confondre les données avec la syntaxe de l'URL.

Pour tester rapidement un cas réel, utilisez notre encodeur URL. Il montre la différence entre encodage complet, encodage de composant et format formulaire.

encodeURI ou encodeURIComponent ?

En JavaScript, les deux fonctions principales ont des rôles différents. encodeURI() sert à encoder une URL complète tout en conservant les séparateurs nécessaires comme :, /, ? et &. Elle est utile si vous avez déjà une URL structurée et que vous voulez seulement rendre certains caractères compatibles.

encodeURIComponent() est beaucoup plus strict. Il encode presque tous les caractères réservés, ce qui le rend adapté aux valeurs individuelles de paramètres. Si un utilisateur recherche café & croissant, vous devez encoder cette valeur avant de construire ?q=.... Sinon, le & sera interprété comme séparateur de paramètre.

const q = "café & croissant";
const url = "/search?q=" + encodeURIComponent(q);
// /search?q=caf%C3%A9%20%26%20croissant

Le piège des redirections OAuth

OAuth et OpenID Connect utilisent souvent un paramètre redirect_uri. Ce paramètre contient lui-même une URL complète, parfois avec sa propre query string. C'est un cas classique d'encodage imbriqué : l'URL de callback doit être encodée comme une seule valeur, sinon le fournisseur d'identité risque de lire ses paramètres internes comme des paramètres de la requête principale.

const callback = "https://app.example.com/callback?state=abc&source=login";
const authUrl = "https://auth.example.com/login?redirect_uri=" +
  encodeURIComponent(callback);

Sans encodeURIComponent(), le &source=login pourrait être traité comme un paramètre du serveur d'authentification, pas comme une partie du callback. Le bug est difficile à repérer car l'URL ressemble visuellement à une URL valide.

Formulaires HTML et espaces transformés en plus

Le format application/x-www-form-urlencoded, utilisé par de nombreux formulaires HTML, remplace souvent les espaces par + plutôt que %20. C'est normal dans ce contexte, mais cela peut surprendre lorsqu'on compare avec encodeURIComponent(). Si vous construisez manuellement des payloads de formulaire, utilisez URLSearchParams : l'API gère les détails d'encodage correctement.

const body = new URLSearchParams();
body.set("name", "Jean François");
body.set("city", "Lyon & Paris");

Double encodage : le bug discret

Un autre problème fréquent est le double encodage. Si une valeur contient déjà %20 et que vous l'encodez à nouveau, le signe pourcentage devient %25. Vous obtenez alors %2520, qui ne se décodera pas comme prévu par le service cible. Ce bug arrive souvent lorsqu'une application reçoit une URL déjà encodée, la stocke, puis la réinjecte dans une autre URL sans distinguer "valeur brute" et "valeur encodée".

La solution est organisationnelle autant que technique : décidez à quel niveau de votre code les valeurs sont encodées. Dans une API interne, transmettez de préférence des valeurs brutes dans des objets structurés, puis encodez uniquement au moment de construire la requête HTTP finale. Évitez de stocker durablement des fragments d'URL encodés si vous pouvez stocker la valeur originale.

Chemins, query strings et fragments

Tous les morceaux d'une URL ne s'encodent pas exactement de la même manière. Un segment de chemin comme /users/Jean François doit préserver les slashs qui séparent les segments, mais encoder l'espace dans le nom. Une valeur de query string doit encoder les séparateurs & et =. Un fragment après # n'est généralement pas envoyé au serveur, mais il peut être interprété par une application front-end.

Les objets natifs URL et URLSearchParams réduisent ces ambiguïtés. Ils produisent un résultat plus fiable que la concaténation manuelle, surtout dans les applications qui manipulent des filtres, des redirections, des liens de partage ou des callbacks d'authentification.

Bonnes pratiques pour les APIs

  • Encodez chaque valeur de paramètre avec encodeURIComponent(), pas la query string entière.
  • Évitez de concaténer de grandes URLs à la main ; préférez URL et URLSearchParams.
  • Ne double-encodez pas une valeur déjà encodée : %20 deviendrait %2520.
  • Documentez clairement si votre API attend une valeur brute ou une valeur déjà encodée.
  • Testez les accents, espaces, esperluettes, slashs et signes plus dans vos cas de test.

À retenir

L'URL encoding n'est pas un détail cosmétique. C'est ce qui permet de distinguer la structure d'une URL des données qu'elle transporte. Une bonne règle mentale : encodez une URL complète avec encodeURI(), mais encodez une valeur de paramètre avec encodeURIComponent(). Pour les formulaires et les requêtes modernes, laissez URLSearchParams faire le travail lorsque c'est possible.