Aller au contenu principal
WHATWG URL Standard §4.4 IETF RFC 3986 Unicode 18.0 UTF-8 Byte-Based %HH Format

Référence d'encodage URL et d'encodage en pourcentage

L'encodage en pourcentage représente des octets arbitraires sous la forme d'un signe pourcentage (%) suivi de deux chiffres hexadécimaux. Les caractères non ASCII sont convertis en octets UTF-8 avant d'être encodés en pourcentage selon l'ensemble d'encodage en pourcentage du composant d'URL spécifique.

Inspecteur d'encodage en pourcentage

Contexte d'URL cible :

Encode sûrement toute valeur destinée à être intégrée dans une partie d'URL. Équivalent au jeu de composants WHATWG et à encodeURIComponent() de JavaScript.

11 car.
Sortie encodée en pourcentage
Valide
hello%20world

Pipeline d'octets UTF-8 : comment les caractères deviennent encodés en pourcentage

WHATWG URL §4.4 & Unicode 18.0

L'encodage en pourcentage opère strictement sur des octets de 8 bits, et non directement sur des caractères Unicode. Quand un caractère non ASCII est introduit dans une URL, il est d'abord sérialisé en ses octets UTF-8, puis chaque octet résultant est représenté par un signe pourcentage (%) suivi de deux chiffres hexadécimaux majuscules.

Étape 1 Glyphe du caractère € Euro Sign
Étape 2 Point de code Unicode U+20AC Valeur scalaire
Étape 3 Octets UTF-8
E2 82 AC
3 octets
Étape 4 URL encodée en pourcentage %E2%82%AC 3 triplets (%HH)
NE codez PAS les points de code directement :

Une erreur technique courante consiste à supposer que U+20AC devient %20AC. Cela produit un espace (%20) suivi des lettres littérales AC ! Dans un traitement d'URL conforme aux normes, chaque caractère non ASCII doit d'abord être converti en octets UTF-8.

Gestion des espaces : quand utiliser %20 plutôt que +

Désambiguïsation critique

L'une des sources de confusion les plus fréquentes chez les développeurs est de savoir si les espaces dans les URL doivent être encodés en %20 ou en +. La réponse est strictement dépendante du contexte :

Spécification d'URL standard

Encodage des chemins, fragments et composants

L'espace est encodé en %20

Entrée : hello world
Résultat : hello%20world
+ littéral : a+b → a+b (préservé)
  • Utilisé par encodeURIComponent() et encodeURI().
  • Obligatoire dans les chemins d'URL (ex. /articles/my%20story/).
  • Dans ce contexte, + représente un signe plus littéral, pas un espace.
Spécification des formulaires HTML

application/x-www-form-urlencoded

L'espace est encodé en +

Entrée : hello world
Résultat : hello+world
+ littéral : a+b → a%2Bb (échappé !)
  • Utilisé par les soumissions de formulaires HTML (POST/GET) et URLSearchParams.
  • Utilisé dans les chaînes de requête au format de données de formulaire (ex. ?q=my+search).
  • Comme + signifie espace, un signe plus littéral doit être encodé en %2B.
Le piège de la recherche « C++ » :

Si un utilisateur recherche C++ dans un paramètre de requête au format application/x-www-form-urlencoded, envoyer ?q=C++ fait que le serveur reçoit C (deux espaces !). Pour préserver les signes plus, le client doit le sérialiser en ?q=C%2B%2B.

Tableau de référence des caractères sensible au contexte

Matrice de normes

Contrairement aux tableaux statiques qui n'affichent qu'une seule valeur, cette matrice de référence montre comment les délimiteurs réservés et les caractères spéciaux sont encodés selon les différents composants d'URL :

Car. Nom et point de code Octets UTF-8 Composant (encodeURIComponent) Données de formulaire (URLSearchParams) Segment de chemin Rôle structurel dans les URL
Space
Space U+0020
20 %20 + %20 Delimiter in HTTP headers, illegal unencoded in URIs
&
Ampersand U+0026
26 %26 %26 %26 Separates parameter pairs in query string and form data
+
Plus Sign U+002B
2B %2B %2B %2B Represents space in form-urlencoded; literal plus must be %2B
/
Forward Slash (Solidus) U+002F
2F %2F %2F %2F Hierarchical segment delimiter in URI path
?
Question Mark U+003F
3F %3F %3F %3F Introduces query string component
#
Number Sign (Hash) U+0023
23 %23 %23 %23 Introduces fragment/anchor identifier
=
Equals Sign U+003D
3D %3D %3D %3D Separates parameter name from value in query string
%
Percent Sign U+0025
25 %25 %25 %25 Introduces percent-encoded byte triplets (%HH)
:
Colon U+003A
3A %3A %3A %3A Terminates scheme; separates userinfo and port number
@
At Sign U+0040
40 %40 %40 %40 Separates userinfo credentials from host authority
€
Euro Sign U+20AC
E2 82 AC %E2%82%AC %E2%82%AC %E2%82%AC Requires 3 UTF-8 bytes (E2 82 AC) before percent-encoding
é
Latin Small Letter E with Acute U+00E9
C3 A9 %C3%A9 %C3%A9 %C3%A9 Requires 2 UTF-8 bytes (C3 A9) before percent-encoding
😀
Grinning Face Emoji U+1F600
F0 9F 98 80 %F0%9F%98%80 %F0%9F%98%80 %F0%9F%98%80 Requires 4 UTF-8 bytes (F0 9F 98 80) before percent-encoding

Comparaison des API JavaScript et web : quelle fonction utiliser ?

Guide du développeur

Choisir la mauvaise fonction d'encodage en JavaScript est l'une des causes les plus fréquentes d'URL cassées et de vulnérabilités de sécurité. Voici la comparaison normative de référence :

encodeURIComponent() JavaScript (ECMAScript)
Idéal pour : Individual query values, path segments, header values
Espaces ( ) : %20
Barres obliques (/) : Encoded as %2F
Délimiteurs : Encodes &, =, ?, #, +, /
encodeURI() JavaScript (ECMAScript)
Idéal pour : Complete URL strings where structural delimiters should remain
Espaces ( ) : %20
Barres obliques (/) : Preserved as /
Délimiteurs : Preserves :, /, ?, #, &, =, +
URLSearchParams Web Standards API (Browser & Node.js)
Idéal pour : Query string serialization and form submission data
Espaces ( ) : + (plus sign)
Barres obliques (/) : Encoded as %2F
Délimiteurs : Encodes &, =, +, #; serializes key=value pairs joined with &
new URL(href) WHATWG URL Standard (Browser & Node.js)
Idéal pour : Full URL parsing, resolution, and normalized serialization
Espaces ( ) : %20 in path and hash; + in searchParams
Barres obliques (/) : Preserves structural path separators
Délimiteurs : Parses scheme, username, password, host, port, path, query, and hash

Modèle d'implémentation moderne recommandé

// 1. Parameter Value Encoding (Safe for query values)
const rawParam = "hello/world & co";
const encodedParam = encodeURIComponent(rawParam);
// → "hello%2Fworld%20%26%20co"

// 2. Query String Construction with URLSearchParams (Best practice)
const params = new URLSearchParams({ search: "C++ language", filter: "active" });
// → "search=C%2B%2B+language&filter=active" (Note: + for space, %2B for literal plus)

// 3. Complete URL Building with new URL()
const url = new URL("https://example.com/api/search");
url.search = params.toString();
// → "https://example.com/api/search?search=C%2B%2B+language&filter=active"

Cas limites : échappements mal formés et pièges du double encodage

Sécurité et analyse

Séquences de pourcentage mal formées

Selon le standard d'URL du WHATWG §4.4, si un signe pourcentage (%) n'est pas suivi de deux chiffres hexadécimaux ASCII, il est conservé comme caractère littéral plutôt que de déclencher une erreur fatale.

Entrée mal formée Décodage WHATWG Avertissement du validateur
100% 100% Signe pourcentage isolé ; doit être encodé en %25 s'il s'agit de données littérales
%2 %2 Séquence d'échappement incomplète ; second chiffre hexadécimal manquant
%GG %GG Caractères non hexadécimaux après %
%20 (double encode) %2520 % encodé en %25 ; le double encodage modifie la signification des données

Piège de sécurité du double encodage

Comme le signe pourcentage est lui-même encodé en %25, encoder une chaîne déjà encodée en change le sens :

Texte original : hello world
→ Premier encodage →
Encodé (%20) : hello%20world
→ Second encodage →
Double encodage (%2520) : hello%2520world
L'invariant strict à passage unique :

Les décodeurs doivent exécuter strictement une seule passe de décodage par action afin d'empêcher des vulnérabilités de sécurité telles que le directory traversal (%252E%252E%252F → %2E%2E%2F).

Normes normatives et provenance des sources

Base vérifiée

Tous les algorithmes d'encodage en pourcentage, les règles de contexte et les représentations d'octets de cette page sont vérifiés par rapport aux spécifications vivantes officielles :

  • WHATWG URL Living Standard — §4.4 Percent-encoded bytes & §5 application/x-www-form-urlencoded (Spécification officielle)
    Somme de contrôle SHA-256 : c4987042a9b2b5883ef59c9b139a04a5bf4d39f75e985ba5740ea5002b8d4f40
  • IETF RFC 3986 — §2 Characters, §2.1 Percent-Encoding, §2.2 Reserved, §2.3 Unreserved (Spécification officielle)
    Somme de contrôle SHA-256 : 2c7921ba101684c8a2b53683a31c586ec6f376fdf243859eaec2b55f69c5e7b5
  • WHATWG HTML Living Standard — §4.10.22.6 Form submission (application/x-www-form-urlencoded) (Spécification officielle)
  • The Unicode Standard, Version 17.0 — Section 3.9 Unicode Encoding Forms (UTF-8) (Spécification officielle)