Encodage d'URL expliqué : pourcentage de codage, encodeURI vs encodeURIComponent et le bogue %2520

11 de juillet de 2026 · 7 min de lecture

Tous les développeurs qui ont construit une URL avec la saisie d'un utilisateur ont rencontré ce problème : un terme de recherche avec un espace ou une esperluette rompt le lien, et tout à coup, la moitié de la requête manque sur le serveur. Le correctif est le codage d'URL, également appelé codage en pourcentage, mais il est livré avec deux fonctions faciles à confondre et un bug qui produit le %2520 déroutant dans vos liens. Ce guide clarifie tout cela.

Pourquoi les URL ont besoin d'être codées

Les URL ne sont autorisées à contenir qu'un ensemble limité de caractères, défini par une norme appelée RFC 3986. Cet ensemble comprend essentiellement des caractères non réservés, des lettres, des chiffres et quelques symboles comme le trait d'union et le trait de soulignement, ainsi qu'une poignée de caractères réservés qui ont une signification structurelle particulière, comme ? pour démarrer une requête, & pour séparer les paramètres, = pour associer une clé à une valeur, / pour les segments de chemin et # pour un fragment. Tout ce qui se trouve en dehors de cet ensemble, espaces, lettres accentuées, emoji ou symbole réservé utilisé comme données plutôt que comme structure, doit être codé, sinon l'URL est interrompue.

Pour ce faire, le codage en pourcentage remplace un caractère non sécurisé par un signe de pourcentage suivi de sa valeur d'octet hexadécimal à deux chiffres. Un espace devient %20. Une esperluette devient %26. Un signe arobase devient %40. À l’autre extrémité, le serveur les décode en caractères d’origine. L'ensemble du système existe pour que du texte arbitraire puisse s'insérer dans la structure rigide d'une URL sans être confondu avec une partie de cette structure.

Le problème central : données vs structure

Voici la situation qui provoque la plupart des bugs. Imaginez une recherche du texte littéral « chats et chiens ». Si vous déposez cela directement dans une chaîne de requête sous la forme q=cats & dogs, le & est lu comme séparateur de paramètre, le serveur voit un paramètre q=cats et un deuxième paramètre sans signification dogs, et votre recherche est interrompue. L'espace pose également problème. L'esperluette doit devenir %26 et l'espace %20 pour que le serveur comprenne qu'ils font partie de la valeur et non de la structure de l'URL. L'encodage est la façon dont vous dites "ce caractère est une donnée, pas un délimiteur".

encodeURI vs encodeURIComponent

JavaScript vous offre deux fonctions d'encodage, et choisir la mauvaise est l'un des bogues d'URL les plus courants. La différence réside dans ce qu'ils considèrent comme « sûr » et qu'ils laissent tranquille.

encodeURIComponent encode tout ce qui est réservé, y compris /? & = # et plus. Il est destiné à coder une valeur unique que vous insérez dans une URL, une valeur de paramètre de requête, un terme de recherche, une cible de redirection. Utilisez-le pour les pièces. encodeURI, en revanche, laisse délibérément les caractères de structure de l'URL (/ ? & =) seuls, car il est destiné à encoder une URL entière déjà assemblée tout en la gardant fonctionnelle. Utilisez-le pour l'ensemble, rarement.

La règle générale : si vous encodez une valeur qui entre dans une URL, utilisez encodeURIComponent. Si vous encodez une URL complète et souhaitez uniquement corriger les caractères illégaux parasites sans casser sa structure, utilisez encodeURI. En cas de doute, vous souhaitez presque toujours encodeURIComponent, car vous codez presque toujours une valeur.

Exemple de mauvais choix : l'utilisation d'encodeURI sur un paramètre de redirection laisse les & et = dans la propre chaîne de requête de la redirection non codés, de sorte que l'URL externe les lit mal. encodeURIComponent sur cette valeur les code en %26 et %3D, en gardant la valeur intacte.

Le bug %2520 : double encodage

Celui-ci confond tout le monde du premier coup. Vous voyez %2520 dans une URL là où vous attendiez %20 et le lien est rompu. Voici ce qui s'est passé : une chaîne déjà encodée a été encodée une seconde fois. Le premier encodage a transformé un espace en %20. Le deuxième codage a ensuite codé le signe de pourcentage lui-même, % devient %25, transformant %20 en %2520. Maintenant, le serveur le décode une fois en %20 (littéralement le texte "%20") au lieu d'un espace, et tout en aval est faux.

La cause est presque toujours le codage d'une valeur qui a déjà été codée, par exemple, la création d'une URL à partir d'une chaîne déjà codée en URL, puis sa réexécution via l'encodeur. La règle pour l’éviter : n’encodez que du texte brut et non codé. N'encodez jamais une URL ou une valeur déjà encodée. Si vous n'êtes pas sûr qu'une chaîne soit déjà codée, décodez-la d'abord, puis encodez-la exactement une fois.

L'ambiguïté du signe plus

Encore un piège. Dans une chaîne de requête, un signe plus (+) est parfois interprété comme un espace, héritage de l'ancien codage de formulaire HTML, application/x-www-form-urlencoded. Mais dans un chemin d’URL, + est un plus littéral. Cette incohérence signifie qu'un + dans vos données peut être lu comme un espace à un endroit et un plus à un autre. La solution la plus sûre consiste à toujours coder un espace sous la forme %20, ce qui est sans ambiguïté partout, plutôt que de compter sur +. Si vous voyez des espaces se transformer en avantages ou vice versa, cette ambiguïté en est généralement la cause.

Les plats pratiques à emporter

Encodez les valeurs que vous mettez dans les URL, utilisez encodeURIComponent pour ces valeurs, encodez uniquement le texte brut pour éviter le bogue de double encodage %2520 et préférez %20 à + pour les espaces. Lorsque vous devez créer ou inspecter une URL à la main, un encodeur et un décodeur rapides vous permettent de voir exactement ce que devient une chaîne et de détecter ces problèmes avant leur expédition.

L'outil d'encodage/décodage d'URL TextCaret encode le texte en pourcentage comme le fait encodeURIComponent, afin que vous puissiez préparer en toute sécurité une valeur de requête ou décoder un mystérieux %2520 pour voir ce qui n'a pas fonctionné, le tout dans votre navigateur.