Encodeur et décodeur d'URL

Codage en pourcentage dans les trois saveurs, côte à côte, afin que vous puissiez voir laquelle vous voulez.

Trois règles, et se tromper de règle est le bug

L’encodage pour cent remplace un caractère par % suivi de la valeur de son octet en hexadécimal. Rien de compliqué. Ce qui pose problème, c’est qu’il existe trois avis différents sur quels caractères doivent être remplacés, et qu’ils divergent précisément sur ceux qui comptent.

RègleÉchappe / ? & = #L’espace devientÀ utiliser pour
encodeURIComponentOui%20Une valeur destinée à une URL
encodeURINon%20Nettoyer une URL complète
Encodage de formulaireOui+Ce qu’envoie un formulaire HTML

L’outil affiche les trois d’un coup, justement pour cette raison. Les lire côte à côte va plus vite que de décider dans l’abstrait laquelle vous vouliez.

L’erreur que cela évite

Supposons une valeur de recherche coffee & cake. Encodée comme composant, elle devient coffee%20%26%20cake, et l’URL est :

/search?q=coffee%20%26%20cake

Un seul paramètre, valeur intacte. Encodée avec encodeURI, l’esperluette survit telle quelle :

/search?q=coffee%20&%20cake

Le serveur voit maintenant deux paramètres : q vaut « coffee » et il en existe un second, vide, nommé « cake ». Rien ne produit d’erreur. La recherche renvoie simplement de mauvais résultats sans rien dire, et c’est le genre de bug qui passe la relecture parce que l’URL a l’air correcte.

Le + qui n’est pas un plus

L’autre source fiable de confusion. Dans des données encodées en formulaire, un + signifie une espace, et le signe plus littéral doit s’écrire %2B. Décoder C%2B%2B avec la règle formulaire donne donc C++, mais décoder C++ donne C — deux espaces, et le nom du langage a disparu.

C’est sur les numéros de téléphone que cela mord le plus fort. +44 20 7946 0958 soumis par un formulaire puis décodé avec la mauvaise règle devient 44 20 7946 0958 : l’indicatif du pays est perdu, et nulle part une erreur n’est signalée.

Que faire plutôt que d’encoder à la main

En JavaScript, construisez vos chaînes de requête avec URLSearchParams au lieu de concaténer. Elle applique la bonne règle à chaque valeur et gère les clés répétées :

const url = new URL('https://example.com/search');
url.searchParams.set('q', 'coffee & cake');
url.searchParams.set('page', '2');
// https://example.com/search?q=coffee+%26+cake&page=2

Tous les autres langages ont un équivalent, et chacun est plus fiable que de trancher caractère par caractère. Cette page sert aux moments où vous lisez une URL que quelqu’un vous a envoyée, ou déboguez une URL qui a déjà mal tourné.

Lire une URL encodée

Quelques séquences valent d’être reconnues au premier regard, car elles reviennent sans cesse dans les journaux :

SéquenceCaractèrePourquoi cela compte
%20espaceDe loin la plus fréquente
%2F/Une barre oblique encodée dans un chemin trahit souvent une tentative de traversée de répertoires
%3A:Courant dans les URL encodées à l’intérieur de paramètres de redirection
%25%Le double encodage apparaît sous la forme %2520
%00nulPresque jamais légitime

%2520 mérite particulièrement d’être connu : c’est %20 encodé une seconde fois. Cela signifie en général qu’une valeur a traversé deux couches qui l’ont chacune encodée, et c’est la signature d’une chaîne de redirections ou d’un proxy qui fait fausse route.

À voir aussi

Pour encoder des octets plutôt qu’échapper du texte, l’autre métier, c’est le Base64. Si la valeur décodée se révèle être du JSON, le formateur vous la lira, et s’il s’agit d’un jeton, ce sera le décodeur de JWT.

Questions sur l’encodage

Quelle est la différence entre encodeURI et encodeURIComponent ?

encodeURIComponent échappe aux caractères qui ont une signification structurelle dans une URL — / ? & = # : et autres - car cela suppose que ce que vous encodez est une valeur qui se trouvera dans une URL. encodeURI les laisse seuls, car il suppose que vous lui transmettez une URL complète qui doit être rangée. L'encodage d'un paramètre de requête avec encodeURI est l'erreur courante : un & à l'intérieur de la valeur survit et divise silencieusement votre paramètre en deux.

Pourquoi un espace est parfois %20 et parfois + ?

Les deux sont corrects dans leur propre contexte. %20 est le pourcentage général de codage pour un espace et fonctionne n'importe où dans une URL. La convention + vient de application/x-www-form-urlencoded, le format dans lequel les formulaires HTML sont soumis, où + signifie un espace et un plus littéral doit être écrit %2B. Ainsi, un espace dans un chemin est %20 et un espace dans les données du formulaire soumis est +. Le décodage des données du formulaire avec la mauvaise règle transforme chaque signe plus dans le texte de l'utilisateur en un espace.

J'ai reçu une erreur d'URI mal formée. Quelle en est la cause ?

Un signe de pourcentage qui n’est pas suivi de deux chiffres hexadécimaux. Habituellement, il s'agit d'un % littéral dans un texte qui n'a jamais été codé — un code de réduction tel que « 50 % de réduction » fera l'affaire, car %20 est lu comme une séquence d'échappement et %off n'est pas valide. Un pourcentage littéral doit être écrit %25. L'autre cause est le double décodage : exécuter decode deux fois sur quelque chose encodé une fois atteint finalement un % qui était censé rester.

Dois-je encoder l’intégralité de l’URL ou uniquement les valeurs ?

Juste les valeurs, essentiellement toujours. Créez structurellement l'URL et encodez chaque paramètre au fur et à mesure que vous l'insérez. En JavaScript, URLSearchParams le fait pour vous et est plus fiable que l'encodage manuel. L'encodage d'une URL complète n'a de sens que lorsque vous en avez reçu une qui est déjà mal formée et que vous la corrigez.

L’encodage d’une URL la rend-elle sûre ?

Non. Le codage en pourcentage concerne la syntaxe et non la sécurité : il garantit qu'une valeur survit à son placement dans une URL sans modifier la structure de l'URL. Cela ne fait rien sur l'endroit où pointe l'URL, et ce n'est pas une défense contre l'injection : une valeur qui a été correctement codée pour une URL est toujours dangereuse si elle est ultérieurement insérée dans HTML ou SQL sans l'échappement approprié.

Dernière vérification . Vous avez repéré quelque chose de dépassé ? Dites-le-nous.