# Chaîne de requête

Une chaîne de requête est une partie d'une URL qui attribue des valeurs à des paramètres spécifiques. Ces paramètres de requête sont en général situés après le chemin d'accès, séparés par un point d'interrogation (?). Une chaîne de requête comprend généralement des champs ajoutés à une URL de base par un navigateur Web ou une autre application cliente, par exemple dans le cadre d'un document HTML, en choisissant l'apparence d'une page ou en accédant à des positions dans un contenu multimédia$^,$$^,$.
Un serveur Web peut gérer une demande HTTP (Hypertext Transfer Protocol) soit en lisant un fichier à partir de son système de fichiers en fonction du chemin de l'URL, soit en traitant la demande à l'aide d'une logique spécifique. Dans les cas où une logique spéciale est invoquée, la chaîne de requête sera utilisée pour ajouter des options à cette logique et utilisée dans son traitement, en complément du composant de chemin de l'URL.

## Structure

Une URL typique contenant une chaîne de requête est la suivante :
   « https://example.com/over/there?name=ferret »
Lorsqu'un serveur reçoit une demande pour une telle page, il peut exécuter un programme, en transmettant la chaîne de requête, qui dans ce cas est name=ferret, inchangée au programme. Le point d'interrogation est utilisé comme séparateur et ne fait pas partie de la chaîne de requête$^,$.
Les frameworks Web peuvent fournir des méthodes pour analyser plusieurs paramètres dans la chaîne de requête, séparés par un délimiteur, en général l'esperluette, " & ", comme dans l'exemple d'URL ci-dessous :
   « https://example.com/path/to/page?name=ferret&color=purple »
La structure exacte de la chaîne de requête n'est pas normalisée. Les méthodes utilisées pour analyser la chaîne de requête peuvent différer d'un site Web à l'autre.
Un lien dans une page Web peut pointer vers une URL qui contient une chaîne de requête. HTML définit trois manières pour un agent utilisateur de générer la chaîne de requête :
* un formulaire HTML via l'élément <form> ... </form>
* une image cliquable côté serveur via l'attribut ismap sur l'élément <img ismap='' />
* une recherche indexée via l'élément désormais obsolète <isindex>

### Formulaires Web

L'une des utilisations initiales des chaînes de requête était de transmettre le contenu d'un formulaire HTML, également appelé formulaire Web. En particulier, lorsqu'un formulaire contenant les champs field1, field2, field3 est soumis, le contenu des champs est encodé sous forme de chaîne de requête comme suit :
   « field1=value1&field2=value2&field3=value3... »
* La chaîne de requête est composée d'une série de paires champ-valeur.
* Dans chaque paire, le nom et la valeur du champ sont séparés par un signe égal, « = ».
* La série de paires est séparée par l'esperluette, « & » (les points-virgules « ; » ne sont plus recommandés par le W3C, voir ci-dessous).
Bien qu'il n'existe pas de standard normalisé, la plupart des frameworks Web permettent d'associer plusieurs valeurs à un seul champ (par exemple field1=value1&field1=value2&field2=value3)$^,$.
Pour chaque champ du formulaire, la chaîne de requête contient une paire field=value. Les formulaires Web peuvent inclure des champs qui ne sont pas visibles pour l'utilisateur ; ces champs sont inclus dans la chaîne de requête lorsque le formulaire est soumis.
Cette convention est une recommandation du W3C. Dans les recommandations de 1999, le W3C recommandait que tous les serveurs Web prennent en charge les séparateurs point-virgule en plus des séparateurs esperluette pour autoriser les chaînes de requête codées application/x-www-form-urlen dans les URL des documents HTML sans avoir à échapper les esperluettes. Depuis 2014, le W3C recommande de n'utiliser que l'esperluette comme séparateur de requête.
Le contenu du formulaire est uniquement encodé dans la chaîne de requête de l'URL lorsque la méthode de soumission du formulaire est GET. Le même encodage est utilisé par défaut lorsque la méthode de soumission est POST, mais le résultat est soumis en tant que corps de requête HTTP plutôt que d'être inclus dans une URL modifiée.

### Recherche indexée

Avant que les formulaires ne soient ajoutés au HTML, les navigateurs rendaient l'élément <isindex> sous la forme d'un contrôle de saisie de texte sur une seule ligne. Le texte entré dans ce contrôle a été envoyé au serveur en tant qu'ajout de chaîne de requête à une requête GET pour l'URL de base ou une autre URL spécifiée par l'attribut action. Cela visait à permettre aux serveurs Web d'utiliser le texte fourni comme critère de requête afin qu'ils puissent renvoyer une liste de pages correspondantes.
Lorsque le texte entré dans le contrôle de recherche indexé est soumis, il est encodé comme une chaîne de requête comme suit :
   « argument1+argument2+argument3... »
* La chaîne de requête est composée d'une série d'arguments en décomposant le texte en mots séparés par des espaces.
* La série est alors séparée par le signe plus, '+'.
Bien que l'élément <isindex> soit obsolète et que la plupart des navigateurs ne le prennent plus en charge ou ne le rendent plus, il existe encore des vestiges de recherche indexée. Par exemple, c'est la source de la gestion spéciale du signe plus, '+' dans le codage en pourcentage de l'URL du navigateur (qui aujourd'hui, avec la dépréciation de la recherche indexée, est presque redondant avec %20). De plus, certains serveurs Web prenant en charge CGI (par exemple, Apache) traiteront la chaîne de requête en arguments de ligne de commande si elle ne contient pas de signe égal, '=' (conformément à la section 4.4 de CGI 1.1). Certains scripts CGI dépendent et utilisent encore ce comportement historique pour les URL intégrées dans HTML.

## Encodage d'URL

Certains caractères ne peuvent pas faire partie d'une URL (par exemple, l'espace) et certains autres caractères ont une signification particulière dans une URL : par exemple, le caractère # peut être utilisé pour spécifier davantage une sous-section (ou un fragment) d'un document. Dans les formulaires HTML, le caractère égal '=' est utilisé pour séparer un nom d'une valeur. La syntaxe générique d'URI utilise le codage d'URL pour traiter ce problème, tandis que les formulaires HTML effectuent des substitutions supplémentaires plutôt que d'appliquer un codage en pourcentage pour tous ces caractères. L'ESPACE est codé comme '+' ou "%20".
HTML 5 spécifie la transformation suivante pour soumettre des formulaires HTML avec la méthode "GET" à un serveur Web. Voici un bref résumé de l'algorithme :
* Les caractères qui ne peuvent pas être convertis dans le jeu de caractères correct sont remplacés par des références de caractères numériques HTML
* L'ESPACE est codé comme '+' ou '%20'
* Lettres (A – Z et a – z), chiffres (0 – 9) et les caractères ' ~ ',' - ',' . ' et ' _ ' sont laissés tels quels
* + est encodé par %2B
* Tous les autres caractères sont encodés sous la forme d'une représentation hexadécimale %HH avec tous les caractères non ASCII encodés d'abord en UTF-8 (ou tout autre encodage spécifié)
L'octet correspondant au tilde (" ~ ") est autorisé dans les chaînes de requête par RFC3986 mais doit être codé en pourcentage dans les formulaires HTML en " %7E ".
L'encodage de SPACE en '+' et la sélection de caractères "tels quels" distinguent cet encodage de [rfc:3986 la RFC 3986].

## Exemple

Si un formulaire est intégré dans une page HTML comme suit :
et l'utilisateur insère les chaînes "this is a field" et "was it clear (already)?" dans les deux champs de texte et appuie sur le bouton d'envoi, le programme test.cgi (le programme spécifié par l' attribut action de l'élément form dans l'exemple ci-dessus) recevra la chaîne de requête suivante : first=this+is+a+field & second=was+it+clear+%28already%29%3F .
Si le formulaire est traité sur le serveur par un script CGI, le script peut généralement recevoir la chaîne de requête sous la forme d'une variable d'environnement nommée QUERY_STRING.

## Suivi

Un programme recevant une chaîne de requête peut en ignorer une partie ou la totalité. Si l'URL demandée correspond à un fichier et non à un programme, toute la chaîne de requête est ignorée. Cependant, que la chaîne de requête soit utilisée ou non, l'intégralité de l'URL, y compris celle-ci, est stockée dans les fichiers journaux du serveur.
Ces faits permettent aux chaînes de requête d'être utilisées pour suivre les utilisateurs d'une manière similaire à celle fournie par les cookies HTTP. Pour que cela fonctionne, chaque fois que l'utilisateur télécharge une page, un identifiant unique doit être choisi et ajouté en tant que chaîne de requête aux URL de tous les liens que la page contient. Dès que l'utilisateur suit un de ces liens, l'URL correspondante est demandée au serveur. Ainsi, le téléchargement de cette page est lié à la précédente.
Par exemple, lorsqu'une page Web contenant les éléments suivants est demandée :
une chaîne unique, telle que e0a72cb2a2c7 est choisie, et la page est modifiée comme suit :
L'ajout de la chaîne de requête ne modifie pas la façon dont la page est présentée à l'utilisateur. Lorsque l'utilisateur suit, par exemple, le premier lien, le navigateur demande la page foo.html?e0a72cb2a2c7 au serveur, qui ignore ce qui suit le ? et envoie la page foo.html comme prévu, en ajoutant également la chaîne de requête à ses liens.
Ainsi, toute demande de page ultérieure de cet utilisateur portera la même chaîne de requête e0a72cb2a2c7, permettant d'établir que toutes ces pages ont été consultées par le même utilisateur. Les chaînes de requête sont souvent utilisées en association avec des pixels espion.
Les principales différences entre les chaînes de requête utilisées pour le suivi et les cookies HTTP sont les suivantes :
* Les chaînes de requête font partie de l'URL et sont donc incluses si l'utilisateur enregistre ou envoie l'URL à un autre utilisateur ; les cookies peuvent être conservés d'une session de navigation à l'autre, mais ne sont ni enregistrés ni envoyés avec l'URL.
* Si l'utilisateur arrive sur le même serveur Web par deux (ou plusieurs) chemins indépendants, deux chaînes de requête différentes lui seront attribuées, tandis que les cookies stockés sont les mêmes.
* L'utilisateur peut désactiver les cookies, auquel cas l'utilisation de cookies pour le suivi ne fonctionne pas. Cependant, l'utilisation de chaînes de requête pour le suivi devrait fonctionner dans toutes les situations.
* Différentes chaînes de requête transmises par différentes visites sur la page signifient que les pages ne sont jamais servies à partir du cache du navigateur (ou du proxy, le cas échéant), augmentant ainsi la charge sur le serveur Web et ralentissant l'expérience utilisateur.
* Les chaînes de requêtes sont visibles explicitement dans la barre d'adresse du navigateur et l'utilisateur peut les voir.

## Problèmes de compatibilité

Selon la spécification HTTP :
   Diverses limitations ad hoc sur la longueur de la ligne de demande sont trouvées dans la pratique. Il est RECOMMANDÉ que tous les expéditeurs et destinataires HTTP prennent en charge, au minimum, des longueurs de ligne de demande de 8000 octets.
Si l'URL est trop longue, le serveur Web échoue avec le code d'état HTTP 414 Request-URI Too Long.
La solution de contournement courante pour ces problèmes consiste à utiliser POST au lieu de GET et à stocker les paramètres dans le corps de la requête. Les limites de longueur des corps de requête sont généralement beaucoup plus élevées que celles de la longueur des URL. Par exemple, la limite de taille POST, par défaut, est de 2 Mo sur IIS 4.0 et 128 Ko sur IIS 5.0. La limite est configurable sur Apache 2 à l'aide de la directive LimitRequestBody, qui spécifie le nombre d'octets de 0 (c'est-à-dire illimité) à 2147483647 (2 Go) qui sont autorisés dans un corps de requête.