Percent-encoding

Un article de Wikipédia, l'encyclopédie libre.
Sauter à la navigation Sauter à la recherche

Le percent-encoding (pouvant se traduire en français par « encodage en pourcent »), également désigné par l'expression URL encoding, est un mécanisme de codage de l'information dans un Uniform Resource Identifier (URI) sous certaines circonstances. Bien qu'il soit connu sous la dénomination d'URL encoding il est, en fait, utilisé de façon plus générale au sein de l'URI principal, qui comprend à la fois l'URL et l'URN. En tant que tel, il est également utilisé dans la préparation des données du type de médias (ou type MIME) application/x-www-form-urlencoded, comme c'est souvent le cas lors de l'envoi de formulaires de données HTML dans les requêtes HTTP.

Percent-encoding dans un URI[modifier | modifier le code]

Types de caractères d'URI[modifier | modifier le code]

Les caractères autorisés dans un URI sont soit réservés (reserved) soit non réservés (unreserved). Ce peut aussi être un caractère de pourcentage % dans le cadre d'un percent-encoding. Les caractères réservés sont ceux qui ont parfois une signification particulière. Par exemple, le caractère de barre oblique est utilisé pour séparer les différentes parties de l'URL (ou, plus généralement, d'un URI). Les caractères non réservés n'ont pas une telle signification. Par le biais du percent-encoding, les caractères réservés sont représentés à l'aide de séquences de caractères. Les ensembles de caractères réservés et non réservés, de même que les circonstances dans lesquelles certains caractères réservés adoptent une signification spéciale, ont légèrement changé avec chaque révision des spécifications qui régissent les URI et les modèles d'URI.

RFC 3986 section 2.2, Caractères Réservés (janvier 2005)
! * ' ( ) ; : @ et = + $ , / ? # [ ]
RFC 3986 section 2.3 Caractères Non Réservés (janvier 2005)
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 - _ . ~

D'autres caractères dans un URI doivent être encodés en pourcent.

Caractères réservés dans le percent-encoding[modifier | modifier le code]

Quand un caractère de l'ensemble réservé (un « caractère réservé ») a une signification spéciale (qu'il est « réservé dans un but ») dans un certain contexte, et qu'un schéma d'URI nécessite d'utiliser le caractère pour certains autres buts, le caractère doit être encodé en pourcent. Encoder en pourcent un caractère réservé implique de convertir le caractère à la valeur correspondante de son octet en ASCII, puis de représenter alors cette valeur sous la forme d'une paire de chiffres hexadécimaux. Les chiffres, précédés par un signe de pourcentage (%) qui est utilisé comme un caractère d'échappement, sont ensuite introduits dans l'URI à la place des caractères réservés. (Dans le cas d'un caractère non-ASCII, celui-ci est généralement converti en sa séquence d'octets en UTF-8, puis chaque valeur d'octet est représentée comme ci-dessous.)

Le caractère réservé, /, par exemple, s'il est utilisé dans la composante « chemin » d'un URI, aura le sens particulier de délimiteur entre les segments du chemin. Si, selon un schéma d'URI, / doit se trouver à l'intérieur d'un segment de chemin, alors les trois caractères %2F ou %2f devront êtres utilisés dans le segment au lieu d'un / brut.

Les caractères réservés après percent-encoding
! # $ et ' ( ) * + , / : ; = ? @ [ ]
%21 %23 %24 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D

Les caractères réservés qui n'ont pas de but réservé dans un contexte particulier peuvent également être encodés en pourcent, mais ne sont pas sémantiquement différents de ceux qui ne le sont pas.

Dans la partie « chaîne de requête » (query string) d'un URI (la partie après un caractère ?), par exemple, / est encore considéré comme un caractère réservé, mais il n'a normalement pas de but réservé, sauf si un schéma particulier d'URI déclare le contraire. Le caractère n'a donc pas besoin d'être encodé en pourcent lorsqu'il n'a pas de but réservé.

Deux URI qui diffèrent uniquement par le fait qu'un caractère réservé est encodé en pourcent dans l'un, alors qu'il apparaît tel quel dans l'autre, ne sont normalement pas considérés comme équivalents (désignant la même ressource), sauf s'il peut être établi que le caractère réservé en question n'a pas de but réservé. Cette détermination dépend des règles établies par chaque schéma d'URI pour les caractères réservés.

Caractères non réservés dans le percent-encoding[modifier | modifier le code]

Les caractères de l'ensemble non réservé ne nécessitent jamais de percent-encoding.

Les URI qui ne diffèrent que par le fait qu'un caractère non réservé est encodé en pourcent ou qu'il apparaît tel quel sont équivalents par définition, mais les interpréteurs d'URI, dans la pratique, peuvent ne pas toujours reconnaître cette équivalence. Par exemple, ils ne devraient pas traiter la chaîne %41 différemment du A ou %7E différemment de ~, mais certains le font. Pour un maximum d'interopérabilité, il est déconseillé aux producteurs d'URI d'encoder en pourcent les caractères non réservés.

Percent-encoding du caractère de pourcentage[modifier | modifier le code]

Parce que le caractère de pourcentage ( % ) sert d'indicateur pour les octets encodés en pourcent, il doit être lui-même encodé sous la forme %25 s'il doit être utilisé comme donnée au sein d'un URI.

Percent-encoding de données arbitraires[modifier | modifier le code]

La plupart des modèles d'URI impliquent la représentation de données arbitraires, telles que l'adresse IP ou un chemin dans un système de fichiers, en tant que composantes d'un URI. Les spécifications du schéma d'URI devraient, mais ne le font souvent pas, fournir une correspondance explicite entre les caractères de l'URI et toutes les valeurs de données possibles étant représentées par ces caractères.

Données binaires[modifier | modifier le code]

Depuis la publication de la RFC 1738, en 1994, il a été spécifié que les modèles qui prévoient la représentation de données binaires dans un URI doivent diviser les données en octets de 8 bits puis encoder en pourcent chaque octet de la même manière que ci-dessus[1]. La valeur d'octet 0x0F, par exemple, devrait être représenté par %0F, mais la valeur d'octet 0x41 peut être représentée par Aou %41. L'utilisation de caractères non encodés ou alphanumériques, ainsi que d'autres caractères non réservés, est généralement préférée car elle produit des URL plus courtes.

Données de caractères[modifier | modifier le code]

La procédure pour encoder en pourcent des données binaires a souvent été extrapolée, parfois de manière inappropriée ou sans être pleinement spécifiée, afin d'être appliquée aux données basées sur les caractères. Durant les débuts du World Wide Web, lorsqu'il s'agissait de traiter les caractères de données du répertoire ASCII et d'utiliser leurs octets correspondants en ASCII en tant que base pour déterminer les séquences encodées en pourcent, cette pratique était relativement inoffensive; il était simplement supposé que les caractères et les octets se correspondaient mutuellement et étaient interchangeables. Le besoin de représenter les caractères en dehors de la plage ASCII a toutefois grandi rapidement et les modèles d'URI ainsi que les protocoles ont souvent échoué à fournir des règles standardisées pour la préparation des données de caractères devant être inclus dans un URI. En conséquence, les applications Web ont commencé à faire usage de différents encodages multi-octets, dynamiques, et d'autres qui n'étaient pas compatibles avec ASCII, en tant que base pour le percent-encoding, ce qui conduisit à des ambiguïtés et de la difficulté pour interpréter les URI de manière fiable.

Par exemple, de nombreux modèles d'URI et des protocoles basés sur les RFC 1738 et 2396 présument que les données de caractères seront converties en octets selon certains codages de caractères avant d'être représentés dans un URI par des caractères non réservés ou par des octets encodés en pourcent. Si le modèle ne permet pas à l'URI de fournir un indice quant à l'encodage utilisé, ou si l'encodage entre en conflit avec l'utilisation de l'ASCII pour  encoder en pourcent des caractères réservés et non réservés, alors l'URI ne peut pas être interprété de manière fiable. Certains modèles échouent complètement à tenir compte de l'encodage et suggèrent simplement à la place que les données de caractères correspondent directement aux caractères de l'URI, ce qui laisse le champ libre aux implémentations pour décider si et comment encoder en pourcent les données des caractères qui ne sont ni dans l'ensemble des réservés ni dans celui des non réservés.

Caractères communs après percent-encoding (ASCII ou UTF-8)
retour à la ligne espace " % - . < > \ ^ _ ` { | } ~
%0A ou %0D ou %0D%0A %De 20 %22 %25 %2D %2E %3C %3E %5C 5E % %5F %60 %7B %7C %7D %7E

Des données de caractères arbitraires sont parfois encodées en pourcent et utilisées dans des situations distinctes des URI, comme c'est le cas des programmes d'offuscation de mot de passe,  ou d'autres protocoles de traduction spécifiques au système.

Standard actuel[modifier | modifier le code]

La syntaxe d'URI générique recommande que les nouveaux modèles d'URI pour la représentation des données de caractère dans un URI représentent, sans les traduire, les caractères de l'ensemble non réservé, et convertissent tous les autres caractères en octets selon le codage UTF-8, pour encoder ensuite ces valeurs en pourcent. Cette suggestion a été introduite en janvier 2005 avec la publication de la RFC 3986. Les modèles d'URI introduits avant cette date ne sont pas concernés.

La spécification actuelle ne traite pas de ce qu'il faut faire avec les données de caractères encodés. Par exemple, dans les ordinateurs, les données de caractère se manifestent sous une forme codée, à un certain niveau, et pourraient donc aussi bien être traitées comme des données binaires ou de caractères lorsqu'elles sont traduites en caractères d'URI. C'est sans doute aux spécifications de modèles d'URI de tenir compte de cette possibilité et de requérir l'un ou l'autre, mais dans la pratique, très peu, si tant est qu'il y en ait, le font réellement.

Implémentations non standard[modifier | modifier le code]

Il existe un encodage non-standard pour les caractères Unicode : %uxxxx, dans lequel xxxx est une unité de code UTF-16 représentée comme quatre chiffres hexadécimaux. Ce comportement n'est pas spécifié par une RFC et a été rejeté par le W3C. La huitième édition de l'ECMA-262 , comporte encore une fonction escape (échappement) utilisant cette syntaxe, avec les fonctions encodeURI et encodeURIComponent, qui servent à appliquer l'encodage UTF-8 à une chaîne de caractères puis à échapper en pourcent les octets qui en résultent[2].

Le type application/x-www-form-urlencoded[modifier | modifier le code]

Lorsque des données qui ont été saisies dans des formulaires HTML sont envoyées, les noms de champs des formulaires et les valeurs sont codées puis envoyées au serveur dans un message de requête HTTP utilisant la méthode GET ou POST, ou, historiquement, via e-mail[3]. L'encodage utilisé par défaut est basé sur une version primitive des règles de percent-encoding des URI[4], avec un certain nombre de modifications telles que la normalisation du saut de ligne et le remplacement des espaces par + au lieu de %20. Le type de support (MIME) des données encodées de cette façon est application/x-www-form-urlencoded, et il est actuellement défini (toujours de manière très désuette) dans les spécifications HTML et XForms. En outre, la spécification CGI contient des règles sur la façon dont les serveurs web décodent les données de ce type et les rendent disponibles aux applications.

Lorsque les données d'un formulaire HTML sont envoyées dans une requête HTTP GET, elles sont incluses dans la chaîne de requête (query string) de l'URI de la demande en utilisant la même syntaxe décrite ci-dessus. Lorsqu'elle sont envoyées dans une requête HTTP POST ou via e-mail, les données sont placées dans le corps du message, et la mention application/x-www-form-urlencoded est incluse dans l'en-tête Content-Type (type de contenu) du message.

Voir aussi[modifier | modifier le code]

Références[modifier | modifier le code]

  1. (en) RFC 1738 §2.2; RFC 2396 §2.4; RFC 3986 §1.2.1, 2.1, 2.5
  2. (en) « ECMAScript® 2017 Language Specification (ECMA-262, 8th edition, June 2017) », Ecma International®
  3. (en) User-agent support for email based [[[HyperText_Markup_Language|HTML]] form submission, using a 'mailto' URL as the form action, was proposed in RFC 1867 section 5.6, during the HTML 3.2 era. Various web browsers implemented it by invoking a separate email program or using their own rudimentary SMTP capabilities. Although sometimes unreliable, it was briefly popular as a simple way to transmit form data without involving a web server or CGI scripts.
  4. (en) T. Berners-Lee, « RFC 1630 », sur IETF Tools, IETF, (consulté le 29 juin 2016)

Liens externes[modifier | modifier le code]

Les spécifications ci-dessous définissent et traitent toutes des caractères réservés, non réservés, et du percent-encoding, sous une forme ou une autre :