Intermédiaire 8 min de lecture 25 janvier 2025

Percent encoding : erreurs fréquentes et solutions pour vos URLs

Tout semble correct, mais vos paramètres disparaissent, une API renvoie 400, une signature HMAC ne correspond plus. Souvent, la cause est un percent encoding mal appliqué. Invisible au premier coup d’œil, décisif à l’exécution. Voici comment le comprendre, l’appliquer correctement et éviter les pièges courants.

Qu'est-ce que le percent encoding ?

C’est le mécanisme standard (RFC 3986) qui représente des octets d’une URL sous la forme %HH (hexadécimal), pour transporter des données sans ambiguïté.

Voici les éléments essentiels à connaître :

1 Caractères réservés en URL

Ils ont un rôle syntaxique et doivent être encodés lorsqu’ils appartiennent aux données.

: / ? # [ ] @ ! $ & ' ( ) * + , ; = %

2 Composants sensibles à l'encodage

Chaque partie de l’URL a ses propres règles d’encodage.

Chemin (/path), Query (?a=b), Fragment (#hash), Host, Userinfo

3 UTF-8 et non-ASCII dans les URLs

Les caractères non-ASCII sont encodés après conversion en bytes UTF-8.

é → UTF-8 C3 A9 → %C3%A9
☕ → E2 98 95 → %E2%98%95
空 → E7 A9 BA → %E7%A9%BA
Emoji (multi-octets) encodés en plusieurs %HH

4 Variantes et pièges courants

Différences d’interprétation selon contexte et bibliothèques :

Espace: %20 vs + (query x-www-form-urlencoded)
Hexa en majuscules/minuscules (%2f ou %2F)
encodeURI vs encodeURIComponent (JS)
Ne pas encoder deux fois: % devient %25

Problèmes classiques

Copier-coller d’URLs déjà encodées

Entraîne un double encodage : % devient %25, les serveurs ne reconnaissent plus le chemin ou les paramètres.

Signatures et vérifications qui échouent

HMAC et checksums calculés sur une version encodée/decodée différente de celle du serveur.

Décodage au mauvais endroit

Confusion entre chemin et query, + traité comme espace alors qu’on attend %2B.

Regex ou parsers naïfs

Comparaisons sur des URL non normalisées, erreurs sur %2F vs /, perte de données.

Exemple de problème courant :

# Deux URLs qui semblent identiques mais ne le sont pas
url1 = "https://api.domain.com/search?q=a+b"
url2 = "https://api.domain.com/search?q=a%20b" # Interprétation différente selon serveur
assert url1 == url2 # ❌ Échec

Symptômes qui doivent vous alerter

🚨 Signaux d'alarme

!
Un diff git montre des changements mais seuls les %HH/espaces varient
!
Des paramètres disparaissent côté serveur (clé absente ou vide)
!
Une signature HMAC varie entre client et backend sans modification apparente
!
Un router n’associe plus une route lorsque %2F est présent dans un segment
!
Un copier-coller d’URL dans un terminal échoue (espaces, guillemets, & non échappés)

Comment les détecter

Solution recommandée : Clean ASCII

Clean ASCII met en évidence les séquences de percent encoding, signale les %HH invalides et aide à visualiser les valeurs encodées/décodées. Vous voyez immédiatement les divergences entre espaces, plus, octets UTF-8 et caractères réservés.

✅ Détection automatique

% non suivi de deux hex, double encodage, mélange + / %20

📊 Analyse complète

Position exacte, octets décodés, différences chemin/query

🧹 Nettoyage automatique

Normalisation RFC 3986, encodage UTF-8, choix %20 ou + selon contexte

💾 Export propre

URL encodée et décodée prêtes à l’emploi

Autres méthodes de détection

Affichage dans l'éditeur

Activez l’affichage des caractères invisibles et surlignage des %HH invalides (plugins URL/URI)
Utilisez un linter URL qui vérifie les encodages dans les fichiers de config et tests

En ligne de commande (Unix)

# Repérer les séquences % invalides
grep -nP "%(?![0-9A-Fa-f]{2})" fichier.txt
# Décoder une URL depuis un fichier
python3 -c "import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read()))" < fichier.txt
# Compter les séquences encodées
grep -oP "%[0-9A-Fa-f]{2}" fichier.txt | sort | uniq -c
# Visualiser les octets après décodage
perl -pe 's/%([0-9A-Fa-f]{2})/chr(hex($1))/eg' fichier.txt | hexdump -C

En code

JavaScript

decodeURIComponent(url) // Erreur si %HH invalide

Python

urllib.parse.quote(texte, safe='-._~')

Excel / Google Sheets

ENCODEURL(A1)

Nettoyer et prévenir

🚀 Solution rapide avec Clean ASCII

Avant d’écrire des scripts maison, utilisez Clean ASCII pour vérifier et normaliser vos URLs en quelques secondes :

Détection des %HH invalides
Normalisation des espaces et réservés
Export encodé/décodé

Méthodes techniques avancées

🔧 Normaliser

Encodez en UTF-8 avant percent encoding (é → %C3%A9)
Conservez les caractères non réservés [-._~] non encodés
Uniformisez la casse hexadécimale (%2F ou %2f) côté client/serveur

🧹 Filtrer

Appliquez encodeURIComponent pour les valeurs de query, encodeURI pour l’URL globale
Décidez explicitement entre + et %20 selon le format attendu
Bloquez les % isolés et les encodages partiels (%A, %GZ)

⚙️ Automatiser

Hooks pre-commit qui refusent les %HH invalides dans les configs et fixtures
Tests de round-trip: encode(decode(x)) == canonical(x)
Linting CI pour vérifier l’usage des fonctions d’encodage adaptées

Checklist rapide

Encodage UTF-8 systématique avant %HH
encodeURIComponent pour les valeurs, encodeURI pour l’ensemble
Règle claire pour espace: %20 ou + selon le backend
Détection des %HH invalides et double encodage
Tests de round-trip et de normalisation d’URL
Documentation équipe sur RFC 3986 et cas particuliers

Conclusion

Le percent encoding paraît simple, mais impacte directement la sécurité, la robustesse et la compatibilité de vos intégrations.

Adoptez une stratégie d’encodage cohérente, normalisez vos URLs et vous éliminerez la majorité des erreurs 400, pertes de paramètres et signatures invalides.

Vérifiez vos URLs percent-encodées maintenant

Utilisez notre outil pour identifier, normaliser et corriger le percent encoding dans vos URLs.

Analyser mes URLs