Outils de développement · Encodeur et décodeur d'URL
Pourquoi + devient un espace lorsque vous décodez une chaîne de requête, et quand ce n'est pas le cas
· Comment ça marche
encodage d'URL javascript flux de travail du développeur
Que + signifie espace dépend du décodeur que vous appelez. Cet article explique comment decodeURIComponent, URLSearchParams et les frameworks de serveur traitent chacun +, et comment éviter de transformer un réel plus en espace.
Pourquoi + devient un espace lorsque vous décodez une chaîne de requête, et quand ce n'est pas le cas
Les soumissions de formulaires HTML utilisent le format application/x-www-form-urlencoded, où l'espace devient plus. Un serveur recevant name=Alice+Smith remplace chaque plus par un espace avant d'extraire la valeur. Lorsqu'un réel plus appartient aux données, comme dans un calcul 5+3, il arrive au serveur sous la forme 5 3 après l'étape de décodage du formulaire. Cette conversion invisible est la racine de la confusion.
Le décodage JavaScript produit des résultats différents selon la fonction que vous utilisez. URLSearchParams traite le plus comme un espace, correspondant au comportement du serveur. Mais decodeURIComponent laisse le plus intact, le traitant littéralement. Cette asymétrie entre les fonctions explique pourquoi la même entrée décode différemment. Un développeur qui s'attend à ce que les deux décodeurs produisent le même résultat découvre que ce n'est pas le cas.
Deux encodages qui se ressemblent – RFC 3986 encodage en pourcentage par rapport à l'application/x-www-form-urlencoded
Deux normes de codage se ressemblent mais fonctionnent différemment. La RFC 3986 définit le codage en pourcentage : tout caractère devient %HH. L'espace devient %20. La norme application/x-www-form-urlencoded ajoute un raccourci : l'espace peut être plus. L'un ou l'autre fonctionne dans un contexte de formulaire, mais plus est facultatif et spécifique à cette norme. Ce sont des domaines différents avec une apparence similaire.
L’appel de decodeURIComponent applique uniquement le décodage RFC 3986. Il lit %20 comme espace et plus comme plus littéral. URLSearchParams applique des règles de décodage de formulaire : les pourcentages d'échappement deviennent leurs caractères et le plus devient un espace. Les deux fonctions résolvent le même problème dans des domaines différents. Les mélanger fait disparaître soit un vrai plus, soit un espace devient un plus et ne parvient pas à se convertir.
decodeURIComponent laisse + seul ; URLSearchParams le transforme en espace — les deux comportements JavaScript comparés
Le comportement du serveur varie, ce qui aggrave le problème. Rails ou Django appliquent automatiquement la règle de forme : le plus devient un espace. Mais l’extraction et le décodage manuel de la chaîne de requête brute avec un décodeur d’URL laisse le plus intact. La même valeur traitée par différents frameworks produit des résultats différents. Le code serveur gère souvent cela implicitement, cachant le problème jusqu'à ce que vous écriviez un décodeur personnalisé.
Exemple : un champ de numéro de téléphone stocke +1-555-0100 avec plus comme indicatif de pays. Un formulaire HTML l'encode comme %2B1-555-0100 car JavaScript a codé plus comme %2B. Le serveur le reçoit. S'il applique le décodage de formulaire, %2B devient plus et la valeur est correcte. Si un proxy supprime l'encodage, l'appel de decodeURIComponent sur le résultat produit +1-555-0100. Chaque couche décode une fois.
Ce que font les serveurs : comportement de framework commun dans la chaîne de requête et le corps de la requête, décrit en termes généraux
JavaScript peut coder des valeurs à l'aide de encodeURIComponent. Étant donné a+b, cela produit a%2Bb. Lorsque cette chaîne codée atteint un serveur ou un décodeur prenant en charge le formulaire, %2B se décode comme plus et le résultat est correct. Si vous encodez à l'aide de la règle de formulaire, un espace devient un plus et un vrai plus devient %2B. Quoi qu'il en soit, l'encodage produit un%2Bb. L'interprétation dépend de la règle de décodage qui s'applique.
Testez l'aller-retour : commencez par a+b. Encodez avec encodeURIComponent pour obtenir un%2Bb. Décodez a%2Bb avec decodeURIComponent et récupérez a+b. Passez a+b à URLSearchParams : il traite le plus comme un espace, produisant un b. Passez a%2Bb à URLSearchParams pour récupérer a+b. La même entrée décodée de deux manières produit des sorties différentes selon le décodeur que vous utilisez.
Exemple concret : 'a+b' et 'a%2Bb' via les deux décodeurs — quatre résultats dans un tableau
Les erreurs courantes suivent directement. Un développeur décode avec decodeURIComponent et se demande pourquoi les données de formulaire entrantes avec un réel plus se cassent. Ils auraient dû utiliser URLSearchParams. À l’inverse, quelqu’un utilise URLSearchParams alors qu’il devrait utiliser decodeURIComponent, et chaque plus littéral disparaît. Le codage deux fois produit % 252B, ce qui nécessite des paires codeur-décodeur correspondantes pour décoder correctement.
Une autre erreur consiste à construire manuellement une chaîne de requête sous la forme ?q=value sans codage. Toute esperluette ou égal dans la valeur crée silencieusement un nouveau paramètre. Le navigateur ne remet pas en question la concaténation ; il considère le résultat comme correctement formé. Seul le codage intentionnel avec encodeURIComponent empêche cela. L'encodeur et le décodeur d'URL affichent les trois fonctions, révélant ce que chacune produit.
Erreurs courantes : décoder deux fois ou coder un espace sous la forme + dans un segment de chemin
La règle de codage de formulaire est appelée application/x-www-form-urlencoded car elle décrit l'en-tête Content-Type du corps de la requête HTTP. Les formulaires HTML sans téléchargement de fichiers envoient le corps dans ce format. Les chaînes de requête dans les URL utilisent également cette convention, même si techniquement, elles n'ont pas de norme de codage officielle. Les spécifications d'URL traitent la requête comme opaque ; plus le sens n’est pas obligatoire. Mais dans les applications Web, plus signifie généralement espace.
Pour garantir un comportement correct, encodez délibérément et décodez avec la fonction matching. Si vous avez encodé avec encodeURIComponent, décodez avec decodeURIComponent. Si vous lisez des données de formulaire HTML ou des corps de requête au format de formulaire, utilisez URLSearchParams. Ne devinez jamais en vous basant sur l’apparence. Une chaîne comme a+b est ambiguë. Les décodeurs ne sont pas interchangeables.
Ce que cela ne couvre pas : données de formulaire en plusieurs parties et corps de requête JSON
Les données des formulaires en plusieurs parties, les corps de requête JSON et d'autres normes ont des règles de codage distinctes. JSON n'utilise pas plus pour l'espace ou le codage en pourcentage ; il utilise des échappements Unicode. Multipart utilise des limites différentes. Cet article couvre uniquement les chaînes de requête et les corps codés sous forme de formulaire, car c'est là que l'ambiguïté positive apparaît. Vérifiez toujours l'en-tête Content-Type et la RFC qui le définit.
Encodez toujours un plus littéral sous la forme %2B lorsqu'il appartient à une valeur de requête. L'encodeur et le décodeur d'URL montrent comment le plus est protégé en tant que %2B en mode composant, séparé des espaces qui deviennent %20. Passez a+b et a%2Bb dans chaque mode, puis examinez les résultats. Cette comparaison montre pourquoi la même entrée décode différemment. La différence réside dans le comportement correct de deux normes différentes.
À retenir : codez toujours un plus littéral sous la forme %2B – comment l'encodeur et le décodeur d'URL montrent à quoi ressemble une valeur en tant que valeur de requête codée en pourcentage
À retenir : plus dans une chaîne de requête est le formulaire codant un raccourci pour l'espace, pas un plus littéral, à moins qu'il ne provienne d'un codage qui l'a protégé en %2B. Un mauvais décodeur perd cette protection. URLSearchParams est le plus sûr dans le JavaScript moderne ; il gère le codage des formulaires et donne accès aux paramètres nommés. Pour les chaînes brutes, encodeURIComponent protège tout ; decodeURIComponent interprète %20 et les pourcentages mais traite plus littéralement.
Testez ceci : construisez ?x=a+b à la main et collez-le dans l'encodeur et le décodeur d'URL. Inspectez-le et regardez URLSearchParams le diviser en paramètre x avec la valeur a b. Collez ?x=a%2Bb et voyez la valeur a+b. Utilisez encodeURIComponent pour créer l'URL et comparer. Cette confirmation visuelle clarifie la règle : les règles de formulaire utilisent plus, le codage en pourcentage utilise %20, leur mélange est la raison pour laquelle plus disparaît dans l'espace.