Comment encoder et décoder des URL
Si vous avez deja vu %20 dans une URL ou un espace devrait etre, ou %C3%A9 ou un caractere accentue devrait apparaitre, vous avez rencontre l'encodage URL. C'est une partie fondamentale du fonctionnement du web, et le comprendre vous aide a deboguer les liens brises, les problemes d'API et les soumissions de formulaires. Un encodeur base sur navigateur gere tout le travail localement sans televerser vos donnees sur un serveur.
Ce que fait l'encodage URL
Les URL ne peuvent contenir en toute securite qu'un ensemble limite de caracteres : lettres (A-Z, a-z), chiffres (0-9) et quelques caracteres speciaux (-, _, ., ~). Tout le reste (espaces, caracteres accentues, emoji, et symboles comme &, =, #, ?) doit etre converti en un format securise.
L'encodage URL (aussi appele encodage pourcent) remplace les caracteres non securises par un % suivi de leurs valeurs d'octet hexadecimales :
| Caractere | Encode |
|---|---|
| Espace | %20 |
| & | %26 |
| = | %3D |
| # | %23 |
| ? | %3F |
| / | %2F |
| @ | %40 |
| : | %3A |
| + | %2B |
| , | %2C |
| ; | %3B |
| (saut de ligne) | %0A |
| (tabulation) | %09 |
Quand vous avez besoin d'encodage URL
- Parametres de requete avec des caracteres speciaux : une requete de recherche comme
prix > 100 & categorie = chaussuresdoit etre encodee pour fonctionner dans une URL - Caracteres non-anglais dans les URL : noms, villes ou contenu dans d'autres langues doivent etre encodes
- Requetes API : lors de la construction manuelle d'appels API, les valeurs de parametres doivent souvent etre encodees
- Debogage : lorsqu'une URL ne fonctionne pas, la decoder revele quelles sont les valeurs reelles
- Liens email (mailto:) : les lignes d'objet et le texte du corps dans les liens mailto doivent etre encodes
- URI de redirection OAuth : le parametre redirect_uri passe aux fournisseurs OAuth doit etre entierement encode
- Charges utiles webhook : chaines de requete dans les URL webhook livrees par des services comme Stripe ou Slack
- Liens profonds vers les applications mobiles : les schemas d'URL personnalises pour les applications iOS/Android necessitent un encodage pour une manipulation sure
- Requetes persistantes GraphQL : les requetes hachees ajoutees en tant que parametres d'URL doivent etre encodees
- Chaines de connexion PostgreSQL : mots de passe et autres caracteres speciaux dans les valeurs DATABASE_URL
Comment encoder et decoder
- Choisissez encoder ou decoder : selectionnez la direction. Choisissez encodeURIComponent pour les parametres de requete ou encodeURI pour les URL completes.
- Collez votre entree : entrez le texte ou l'URL. Le resultat se met a jour instantanement.
- Copiez la sortie : utilisez le resultat dans votre code, requete API ou navigateur.
Une breve histoire de l'encodage URL
L'encodage URL a ete defini par le RFC 1738 en decembre 1994, parallelement a la specification URL originale. Le RFC a ete redige par Tim Berners-Lee (inventeur du web) avec la contribution du groupe de travail URI de l'IETF. Le schema d'encodage original utilisait des valeurs d'octet ASCII : chaque caractere reserve ou non securise etait encode comme % suivi de deux chiffres hexadecimaux.
L'encodage a ete mis a jour plusieurs fois :
- RFC 1738 (1994) : specification URL originale, ASCII uniquement
- RFC 2396 (1998) : syntaxe plus rigoureuse, separation des caracteres «reserves» des «non reserves»
- RFC 3986 (2005) : specification URI actuelle, definit deux modes d'encodage (chemin vs requete), sequences d'octets UTF-8 pour non-ASCII
- WHATWG URL Standard (en cours) : la specification vivante standard du navigateur, utilisee par tous les navigateurs modernes, regles legerement differentes du RFC 3986 pour la retrocompatibilite
Le plus grand changement a ete le passage a UTF-8 dans le RFC 3986. Avant cela, les URL encodees etaient ASCII uniquement, et les caracteres non latins necessitaient des solutions de contournement (Punycode pour les domaines, IDN pour les adresses internationales). Aujourd'hui, un «é» accentue dans une URL s'encode en %C3%A9 (ses deux octets UTF-8), pas l'octet Latin-1 %E9 que les anciens systemes produiraient.
encodeURI vs encodeURIComponent vs encodeURIFull
JavaScript a trois fonctions d'encodage avec un comportement subtilement different :
| Fonction | Ce qu'elle encode | Ce qu'elle preserve | Utiliser pour |
|---|---|---|---|
| encodeURI() | Tous les caracteres non securises | Syntaxe URL : : / ? & = # | Encoder des URL entieres |
| encodeURIComponent() | Tous les caracteres non securises y compris la syntaxe URL | Seulement A-Z a-z 0-9 - _ . ~ ! * ' ( ) | Valeurs de parametres de requete |
| escape() (depreciee) | La plupart des caracteres non securises | Latin-1 uniquement | Ne pas utiliser |
En Python :
urllib.parse.quote()est comme encodeURI (preserve /, mais pas :)urllib.parse.quote_plus()est comme encodeURIComponent mais utilise + pour les espacesurllib.parse.urlencode(dict)encode des chaines de requete entieres
Dans d'autres langages :
| Langage | Encodage de composant | Encodage URI complet |
|---|---|---|
| Java | URLEncoder.encode() (avec des reserves autour de +) | URI.toASCIIString() |
| C# | Uri.EscapeDataString | Uri.EscapeUriString |
| Ruby | CGI.escape() | URI.encode_www_form_component |
| PHP | rawurlencode() | urlencode() (note : %2B vs +) |
| Go | url.QueryEscape() | url.PathEscape() |
| Rust | crate percent_encoding | crate percent_encoding |
Pieges courants
- Encoder l'URL entiere : si vous encodez
https://example.com/search?q=hello, vous obtenezhttps%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dhelloqui n'est plus une URL fonctionnelle. N'encodez que les valeurs, pas les caracteres structurels. - Double encodage : encoder une chaine deja encodee produit des choses comme
%2520(le%est encode comme%25). Si votre URL semble fausse, verifiez si quelque chose est encode deux fois. - Espaces comme + vs %20 : dans
application/x-www-form-urlencoded(corps POST de formulaire), les espaces deviennent+. Dans les URL, les espaces deviennent%20. La plupart des serveurs acceptent les deux, mais certains analyseurs stricts non. - Encodage incorrect des caracteres reserves :
?,#,&,=ont une signification speciale dans la syntaxe URL. S'ils apparaissent dans une valeur, ils doivent etre encodes ; s'ils apparaissent comme syntaxe, ils ne doivent pas l'etre. - Oublier de decoder a la reception : si vous encodez une valeur, l'envoyez, puis votre serveur lit
?q=hello%20worldlitteralement sans la decoder, votre application voithello%20worldet nonhello world. La plupart des frameworks decodent automatiquement, mais verifiez dans le code personnalise. - Confusion du signe plus :
+est un plus litteral dans les segments de chemin et un espace dans les chaines de requete. Encodez les vrais signes plus comme%2Bdans les valeurs de requete pour eviter l'ambiguite. - UTF-8 vs autres encodages : si votre URL contient «résumé» et que le serveur attend Latin-1 au lieu d'UTF-8, vous pouvez obtenir du mojibake. Le web moderne est UTF-8 ; les systemes hérités non.
- Limites de longueur d'URL : meme s'il n'y a pas de limite stricte dans la specification, les navigateurs et serveurs limitent souvent les URL a 2048-8192 caracteres. Les donnees fortement encodees peuvent atteindre les limites plus rapidement que prevu.
- Cookies et en-tetes Referer : les URL sont passees dans les en-tetes Referer et peuvent etre enregistrees. Les donnees sensibles dans les URL (mots de passe, tokens) fuient vers les journaux et l'analyse. Utilisez des corps POST pour les donnees sensibles.
- Noms de domaine non-ASCII : les domaines utilisent Punycode (RFC 3492), pas l'encodage pourcent. «münchen.de» devient «xn--mnchen-3ya.de» dans les recherches DNS, pas «m%C3%BCnchen.de».
Exemples travailles
| Entree | encodeURI | encodeURIComponent |
|---|---|---|
hello world | hello%20world | hello%20world |
q=test&page=1 | q=test&page=1 | q%3Dtest%26page%3D1 |
https://x.com/path | https://x.com/path | https%3A%2F%2Fx.com%2Fpath |
caf é | caf%20%C3%A9 | caf%20%C3%A9 |
中文 | %E4%B8%AD%E6%96%87 | %E4%B8%AD%E6%96%87 |
100% | 100%25 | 100%25 |
email@test.com | email@test.com | email%40test.com |
Conseils
- Encoder les valeurs, pas les URL entieres : si vous encodez une URL entiere, les barres obliques et les deux-points qui structurent l'URL seront egalement encodes, la cassant. N'encodez que les valeurs dans les parametres de requete.
- Double encodage : encoder une chaine deja encodee produit des choses comme
%2520(le%est encode comme%25). Si votre URL semble fausse, verifiez si quelque chose est encode deux fois. - Decoder pour le debogage : lorsqu'une requete API echoue ou qu'une URL semble brouillee, la decoder pour voir les valeurs reelles des parametres. Cela revele souvent le probleme immediatement.
- Utiliser les fonctions integrees de votre langage : en code de production, utilisez toujours
encodeURIComponent()(JavaScript),urllib.parse.quote()(Python) ouURLEncoder.encode()(Java) plutot que d'encoder a la main. - Tester avec des cas limites : essayez des entrees avec espaces, accents, emoji et caracteres speciaux. Si votre encodage fonctionne pour tous, il fonctionne.
- Verifier dans la barre d'adresse du navigateur : collez votre URL encodee dans un navigateur. Si la page se charge, l'URL est bien formee. Sinon, votre encodage a un bogue.
- Utiliser une bibliotheque de chaines de requete pour les cas complexes : construire une chaine de requete a partir d'un dictionnaire ou d'un objet (
?a=1&b=2&c=3) est plus facile et plus sur avec une fonction de bibliotheque (urlencode en Python, URLSearchParams en JavaScript) qu'un assemblage manuel. - Connaitre la difference entre encodage de chemin et de requete : une barre oblique
/dans un segment de chemin est structurelle ; dans une valeur de requete, elle doit etre encodee. Le RFC 3986 a des regles differentes pour chacun.
Confidentialite et URL sensibles
L'encodeur et le decodeur URL s'executent entierement dans votre navigateur. Les URL que vous collez, le traitement intermediaire et la sortie encodee/decodee restent tous sur votre appareil. Rien n'est televerse sur un serveur, enregistre ou partage avec qui que ce soit.
Cela importe car les URL contiennent frequemment des donnees extremement sensibles : cles et tokens d'API dans les parametres de requete, codes d'autorisation OAuth qui accordent l'acces au compte, ID de session, URL signees pour des compartiments S3 prives avec identifiants integres, tokens de connexion par lien magique, URL de reinitialisation de mot de passe, URL internes d'administration qui revelent la structure du produit, adresses e-mail des clients dans les liens de desabonnement, donnees personnelles dans les soumissions de formulaires. Les encodeurs URL en nuage enregistrent chaque collage, les conservent parfois pour «amelioration du service», et ont ete impliques dans de vraies fuites ou des tokens d'authentification colles ont ete extraits par des attaquants surveillant les journaux. Un encodeur base sur navigateur a une exposition nulle : l'URL ne quitte jamais votre machine.
L'encodage base sur navigateur fonctionne aussi hors ligne une fois la page chargee, utile pour encoder des URL dans les avions, dans des environnements securises sans acces internet, ou partout ou vous ne pouvez pas ou ne devriez pas coller des URL portant l'authentification dans un service tiers.
Questions fréquentes
Quelle est la différence entre encodeURI et encodeURIComponent ?
encodeURI préserve les caractères valides dans une structure d'URL (barres, deux-points, points d'interrogation). encodeURIComponent encode tout sauf les lettres, les chiffres et quelques caractères sûrs. Utilisez encodeURIComponent pour les valeurs de paramètres de requête, encodeURI pour les URL complètes.
Pourquoi les espaces deviennent-ils %20 ou + ?
Dans l'encodage d'URL, les espaces deviennent %20. Dans les données de formulaire (application/x-www-form-urlencoded), les espaces deviennent +. Les deux sont valides dans leurs contextes, mais %20 est le standard universel pour les URL.
Dois-je encoder mes URL manuellement ?
Dans la plupart des cas, votre langage ou framework s'occupe de l'encodage automatiquement. L'encodage manuel est utile quand vous construisez des URL à la main, déboguez des requêtes d'API ou travaillez avec des chaînes de requête contenant des caractères spéciaux.
Mes données sont-elles envoyées sur un serveur ?
Non. Tout l'encodage et le décodage se font dans votre navigateur.