Encodage URL expliqué : l'encodage pourcent dans les requêtes HTTP
Découvrez pourquoi les caractères spéciaux cassent les URL, comment fonctionne l'encodage pourcent au niveau des octets, la différence critique entre encodeURI et encodeURIComponent, et les bugs d'encodage courants dans les applications réelles.
Les URL semblent simples de l'extérieur — une chaîne de texte pointant vers une ressource. Mais sous le capot, elles suivent une grammaire stricte qui n'autorise qu'un ensemble précis de caractères. Dès que vous tentez d'insérer un espace, une esperluette ou un caractère non-ASCII dans une URL sans l'encoder, les choses se brisent d'une façon difficile à déboguer. L'encodage pourcent (communément appelé encodage URL) est le mécanisme qui permet d'intégrer des données arbitraires de façon sûre dans une URL.
Vous pouvez encoder et décoder des URL instantanément avec l'outil Encodeur/Décodeur d'URL BrowseryTools — gratuit, sans inscription, tout reste dans votre navigateur.
Pourquoi les caractères spéciaux cassent les URL
La spécification URL (RFC 3986) réserve certains caractères à des fins structurelles. Le ? sépare le chemin de la chaîne de requête. Le & sépare les paramètres de requête entre eux. Le # marque un identifiant de fragment. Le / sépare les segments de chemin. Si vos données contiennent l'un de ces caractères, un analyseur d'URL ne peut pas distinguer vos données de la structure de l'URL elle-même.
Considérons une recherche pour rock & roll. En construisant naïvement l'URL :
/search?q=rock & roll
^ ^
| └── looks like a new parameter begins here
└── this & splits q from a phantom second parameterL'analyseur lit q=rock (avec un espace en fin) comme premier paramètre, puis rencontre ce qui ressemble au début d'un second paramètre nommé roll. Les deux valeurs sont incorrectes. L'URL correcte est /search?q=rock%20%26%20roll — l'espace devient %20 et l'esperluette devient %26.
Ce que fait réellement l'encodage pourcent
L'encodage pourcent convertit un octet en une séquence de trois caractères : un signe pourcent littéral suivi de deux chiffres hexadécimaux majuscules représentant la valeur de l'octet. Le caractère espace (octet ASCII 32, hex 0x20) devient %20. Le signe arobase (@, ASCII 64, hex 0x40) devient %40. La règle est :
percent-encode(byte) = "%" + byte.toString(16).toUpperCase().padStart(2, "0") Examples: space (0x20) → %20 @ (0x40) → %40 [ (0x5B) → %5B € (UTF-8: 0xE2 0x82 0xAC) → %E2%82%AC
Pour les caractères Unicode multi-octets (tout ce qui est hors ASCII), le caractère est d'abord encodé en octets UTF-8, puis chaque octet est encodé en pourcent. Le signe euro € est composé de trois octets UTF-8, il devient donc trois séquences encodées en pourcent : %E2%82%AC.
Caractères sûrs vs caractères réservés
Tous les caractères n'ont pas besoin d'être encodés. La RFC 3986 définit deux ensembles utilisables tels quels :
- Caractères non réservés — A–Z, a–z, 0–9, tiret, underscore, point, tilde. Ces caractères n'ont aucune signification spéciale et n'ont jamais besoin d'être encodés.
- Caractères réservés —
: / ? # [ ] @ ! $ & ' ( ) * + , ; =. Ils sont sûrs dans leurs positions structurelles, mais doivent être encodés lorsqu'ils apparaissent en tant que valeurs de données.
Tout le reste — espaces, Unicode, caractères de contrôle, la plupart des signes de ponctuation — doit toujours être encodé.
encodeURI vs encodeURIComponent : la différence critique
JavaScript propose deux fonctions d'encodage intégrées, et les confondre est l'un des bugs d'encodage URL les plus courants dans les applications web.
encodeURI() est conçu pour encoder une URL complète. Il laisse tous les caractères réservés intacts car ils ont une signification structurelle dans une URL complète. À utiliser si vous avez une URL complète qui pourrait contenir des espaces ou de l'Unicode mais qui a une structure valide :
encodeURI("https://example.com/search?q=hello world&lang=en")
// → "https://example.com/search?q=hello%20world&lang=en"
// ✓ space encoded, but & and ? left intactencodeURIComponent() est conçu pour encoder une valeur individuelle — la valeur d'un paramètre de requête, un segment de chemin, tout ce qui doit être traité comme une donnée brute. Il encode également les caractères réservés, dont &, =, ? et / :
encodeURIComponent("rock & roll")
// → "rock%20%26%20roll"
// ✓ & encoded — safe to use as a query parameter value
encodeURIComponent("https://example.com/page")
// → "https%3A%2F%2Fexample.com%2Fpage"
// ✓ colons and slashes encoded — safe as a redirect_uri valueLa règle à retenir : lors de la construction d'une URL, utilisez encodeURIComponent() sur chaque valeur de paramètre individuelle, jamais sur l'URL complète. N'utilisez encodeURI() que sur une URL complète à normaliser. Dans le code moderne, préférez les API URL et URLSearchParams à l'encodage manuel — elles gèrent l'encodage automatiquement et correctement.
Pièges de l'encodage de chaîne de requête
Plusieurs bugs subtils reviennent régulièrement lors de l'encodage de chaînes de requête. Le signe + mérite une attention particulière : dans le format application/x-www-form-urlencoded (le format utilisé par les formulaires HTML), un espace est encodé en + plutôt qu'en %20. Il s'agit d'une convention héritée qui précède la RFC 3986. Si votre backend décode selon les règles d'encodage de formulaire et que votre frontend envoie %20, cela fonctionne. Mais si le frontend envoie + et que votre backend décode selon les règles RFC 3986, le + est conservé comme signe plus littéral — pas comme un espace.
// URLSearchParams uses application/x-www-form-urlencoded (+ for spaces)
new URLSearchParams({ q: "rock & roll" }).toString()
// → "q=rock+%26+roll"
// encodeURIComponent uses RFC 3986 (%20 for spaces)
"q=" + encodeURIComponent("rock & roll")
// → "q=rock%20%26%20roll"
// Both are valid — just be consistent on both endsComment les données de formulaire sont encodées en URL
Lorsqu'un formulaire HTML est soumis avec method="GET", le navigateur sérialise les champs du formulaire en une chaîne de requête utilisant application/x-www-form-urlencoded. Chaque nom et valeur de champ est encodé (espaces en +, caractères spéciaux en %XX), et les champs sont joints par &. Pour les formulaires method="POST" sans attribut enctype, le même encodage est utilisé mais les données sont envoyées dans le corps de la requête plutôt que dans l'URL.
C'est également le format utilisé par fetch() lorsqu'on lui passe un objet URLSearchParams comme corps, et c'est ce que la plupart des frameworks côté serveur décodent automatiquement lors de la lecture des soumissions de formulaires.
Base64 dans les URL
Le Base64 standard utilise + et / — deux caractères ayant une signification spéciale dans les URL. Lorsque des données encodées en Base64 doivent apparaître dans une URL (cas courant pour les jetons, les données d'image ou les signatures cryptographiques), utilisez plutôt la variante Base64URL. Elle remplace + par - et / par _, produisant une chaîne sûre dans n'importe quelle position d'une URL sans encodage supplémentaire. Les JWT utilisent ce format pour leurs segments d'en-tête et de charge utile.
Bugs d'encodage courants en production
Quelques patterns de bugs qui reviennent fréquemment dans les applications en production :
- Double encodage — encoder une URL déjà encodée.
%20devient%2520car%lui-même est encodé en%25. Vérifiez toujours si une valeur est déjà encodée avant de l'encoder à nouveau. - Oubli d'encodeURIComponent sur redirect_uri — les flux OAuth passent un
redirect_urien tant que paramètre de requête. S'il contient un?ou un&non encodé, le serveur d'autorisation analyse ces caractères comme faisant partie de la structure de l'URL externe, ce qui casse la redirection. - Encodage non UTF-8 — les systèmes anciens ou mal configurés encodent parfois en ISO-8859-1 au lieu d'UTF-8. La séquence d'octets pour
édiffère entre les deux. Imposez UTF-8 de manière cohérente des deux côtés. - Journalisation d'URL brutes — journaliser une URL contenant des données utilisateur encodées peut produire des journaux trompeurs si votre outil de visualisation décode automatiquement les séquences pourcent, masquant ce qui a réellement été envoyé sur le réseau.
Encodez et décodez des URL instantanément
Que vous déboguiez une redirection OAuth, construisiez une chaîne de requête à la main, inspectiez une requête API malformée ou essayiez simplement de comprendre ce que contient réellement une URL encodée en pourcent — l'outil Encodeur/Décodeur d'URL BrowseryTools le fait instantanément. Collez votre chaîne, choisissez encoder ou décoder, et voyez le résultat immédiatement. Aucun appel serveur, sans inscription.
Encodeur / Décodeur d'URL gratuit — 100 % dans votre navigateur
Ouvrir l'encodeur d'URL →Try the Tools — 100% Free, No Sign-Up
Everything runs in your browser. No uploads. No accounts. No ads.
Explore All Tools →