Les URL ne peuvent contenir qu'un jeu restreint de caractères ASCII. Tout le reste — espaces, accents, emoji, et la ponctuation que les URL utilisent structurellement — doit s'écrire sous forme d'un signe pourcent suivi de la valeur de l'octet en hexadécimal. L'encodage pourcent, c'est tout cela. L'intéressant est de savoir quels caractères encoder, car en encoder trop casse une URL tout aussi sûrement que ne pas en encoder assez.
Il y a deux encodeurs, et se tromper casse des choses
JavaScript propose encodeURI et encodeURIComponent, et ils diffèrent d'exactement onze caractères : # $ & + , / : ; = ? @. encodeURI les laisse tranquilles ; encodeURIComponent les échappe.
Cette liste n'est pas arbitraire — ce sont précisément les caractères qui ont un sens structurel dans une URL. La barre oblique sépare les segments de chemin, le point d'interrogation ouvre la requête, l'esperluette sépare les paramètres, le dièse commence le fragment. La règle en découle directement : utilisez encodeURI quand vous avez une URL entière et voulez laisser son squelette intact. Utilisez encodeURIComponent quand vous avez une valeur unique sur le point d'être insérée dans une URL — un paramètre de requête, un segment de chemin.
Inversez-les et l'échec est silencieux. Encodez une URL entière avec encodeURIComponent et vous obtenez une chaîne où https%3A%2F%2F n'est plus un schéma, et rien ne l'atteindra. Encodez une valeur de requête avec encodeURI et une valeur contenant & se scinde silencieusement en deux paramètres — ce qui n'est pas seulement un bug, c'est le mécanisme même de l'injection de paramètres. Cet outil échappe le jeu complet dit « component », le choix sûr pour le cas courant : encoder une valeur.
Le signe plus n'est pas une espace, sauf quand il l'est
C'est le piège le plus subtil du sujet, et il est réellement ambigu, pas simplement déroutant. Dans la RFC 3986, la spécification qui régit les URL, une espace s'écrit %20 et un plus est un plus littéral. Mais les formulaires HTML n'utilisent pas la RFC 3986 — ils utilisent application/x-www-form-urlencoded, une convention plus ancienne où une espace s'écrit +.
Résultat : la même chaîne se décode de deux façons selon qui la lit. decodeURIComponent("a+b") renvoie "a+b", en gardant le plus. new URLSearchParams("q=a+b").get("q") renvoie "a b", en le transformant en espace. Aucune n'a tort ; elles appliquent des spécifications différentes. C'est pourquoi une recherche de « C++ » arrive si souvent en « C » — quelque chose dans la chaîne a appliqué les règles des formulaires à une URL.
En pratique : dans une chaîne de requête, supposez que + signifie espace, car c'est ce que supposent les navigateurs et pratiquement tous les cadres serveur. Partout ailleurs dans une URL — segment de chemin, fragment — un plus est un plus. La case RFC 1738 de cette page bascule la sortie vers la convention des formulaires exactement pour cette raison.
Pourquoi décoder « 100% » lève une erreur
Dans une URL encodée, le signe pourcent n'est pas un caractère ordinaire — c'est un marqueur d'échappement, et le décodeur exige exactement deux chiffres hexadécimaux après lui. Donnez la chaîne "100%" à decodeURIComponent et il ne renvoie pas "100%" ; il lève URIError: URI malformed, car il n'y a rien à lire après le pourcent.
Cela remonte sans arrêt avec de vraies données. Codes de réduction, statistiques, tout ce qui contient un pourcent littéral fera tomber un décodeur, sauf si le pourcent a lui-même été encodé en %25 à l'aller. Si vous voyez URIError sur des données utilisateur, le bug est presque toujours en amont : quelque chose a construit l'URL par concaténation de chaînes au lieu d'encoder chaque valeur correctement.
Les caractères non ASCII deviennent plusieurs octets chacun
L'encodage pourcent opère sur des octets, pas sur des caractères, et les URL modernes transportent de l'UTF-8. Un caractère hors ASCII devient donc un échappement par octet : é fait deux octets et s'encode en %C3%A9, tandis qu'un emoji fait quatre octets et devient douze caractères d'échappement.
Bon à retenir quand une limite de longueur entre en jeu. Un chemin ou un paramètre qui paraît confortablement court en japonais ou en arabe peut être trois fois plus long une fois encodé, et certains systèmes imposent encore des limites autour de 2000 caractères pour l'URL entière.
Questions fréquentes
Mon URL est-elle envoyée à un serveur ?
Non. Cet outil porte la mention « client » : l'encodage s'exécute dans votre onglet et le texte ne quitte jamais votre machine. Cela mérite d'être signalé car les URL issues de vrais systèmes transportent souvent des jetons de session, des clés d'API ou des identifiants clients dans leur chaîne de requête — si c'est le cas de la vôtre, traitez-la comme un identifiant, quel que soit l'outil où vous la collez.
Dois-je utiliser + ou %20 pour une espace ?
%20 fonctionne toujours — il est valide dans toutes les parties d'une URL et tous les décodeurs le comprennent. + ne signifie espace que dans une chaîne de requête, et seulement sous les règles des formulaires. Dans le doute, utilisez %20 ; ce n'est jamais faux. N'utilisez + que si vous produisez délibérément des données de formulaire et savez que le lecteur les attend.
Mon URL encodée contient %2520. Que s'est-il passé ?
Double encodage. %25 est un signe pourcent encodé, donc %2520 est ce qu'on obtient quand %20 repasse une seconde fois dans un encodeur — le % est devenu %25 et le 20 a suivi. Quelque chose dans votre chaîne encode une valeur déjà encodée. Encodez exactement une fois, à l'endroit où vous construisez l'URL, et jamais sur une chaîne que vous n'avez pas construite vous-même.
Pourquoi mon esperluette coupe-t-elle mon paramètre en deux ?
Parce qu'elle n'a pas été encodée lors de la construction de la valeur. Dans une chaîne de requête, & est le séparateur entre paramètres : une valeur contenant un & brut est indiscernable du début d'un nouveau. Il faut qu'elle devienne %26. C'est aussi le mécanisme derrière l'injection de paramètres, mieux vaut donc corriger proprement là où vous construisez l'URL plutôt que de rustiner le symptôme.
Dois-je encoder une URL prise dans la barre d'adresse ?
Presque certainement pas — elle est déjà encodée, et la réencoder produit le problème du %2520 ci-dessus. Les navigateurs affichent une version décodée et lisible tout en conservant la version encodée en interne. Ce que vous voyez n'est pas ce qui est envoyé. Si une URL contient déjà des échappements %, c'est qu'elle a été encodée : décodez-la pour la lire, ne l'encodez pas à nouveau.