web-dev-qa-db-fra.com

Quels caractères doivent être échappés dans une chaîne de requête HTTP?

Cette question concerne les caractères de la partie chaîne de requête de l'URL, qui apparaissent après le caractère de marque ?.

Selon Wikipedia , certains caractères sont laissés tels quels et d'autres sont encodés (généralement avec une séquence d'échappement %).

J'ai essayé de retracer cela selon les spécifications réelles, afin de comprendre la justification derrière chaque puce de cette page Wikipedia.

Exemple de contradiction 1:

Le spécification HTML dit d'encoder l'espace comme + Et reporte le reste à RFC1738 . Cependant, ce RFC dit que ~ Est dangereux et en outre que "[tous] les caractères dangereux doivent toujours être encodés dans l'URL". Cela semble contredire Wikipedia.

En pratique, IE8 code ~ Dans les chaînes de requête qu'il génère, tandis que FF3 le laisse tel quel.

Exemple de contradiction 2:

Wikipedia déclare que tous les caractères qu'il ne mentionne pas doivent être encodés. ! N'est pas mentionné dans Wikipedia. Mais RFC1738 indique que ! Est un caractère "spécial" et "peut être utilisé non codé". Cela semble contredire Wikipedia qui dit qu'il doit être encodé.

En pratique, IE8 code ! Dans les chaînes de requête qu'il génère, tandis que FF3 le laisse tel quel.

Je comprends que la morale de cela va probablement être de coder les caractères qui sont dans le doute entre Wikipedia et les spécifications. Peut-être même aller jusqu'à encoder tout ce qui n'est pas [A-Za-z0-9]. Je voudrais juste connaître les normes réelles à ce sujet.

Conclusions

L'algorithme décrit sur Wikipedia code précisément les caractères qui ne sont pas RFC3986 caractères non réservés . Autrement dit, il code tous les caractères autres que les caractères alphanumériques et -._~. Dans un cas particulier, l'espace est codé comme + Au lieu de %20 Par RFC3986.

Certaines applications utilisent une ancienne RFC. A titre de comparaison, les RFC2396 caractères non réservés sont alphanumériques et !'()*-._~.

À titre de comparaison, algorithme de brouillon de travail HTML5 code tous les caractères autres que les caractères alphanumériques et *-._. Le codage de cas spécial pour l'espace reste +. Les différences notables sont que * N'est pas codé et ~ Est codé. (Techniquement, cette gestion de * Est compatible avec RFC3986 même si * Est dans reserved car c'est dans le sub-delims Qui est autorisé dans le query production.)

46
Jason Kresowaty

La réponse se trouve dans le document RFC 3986, en particulier Section 3.4 .

Le composant de requête est indiqué par le premier caractère de point d'interrogation ("?") Et terminé par un caractère de signe numérique ("#") ou par la fin de l'URI.

...

La barre oblique ("/") et le point d'interrogation ("?") Peuvent représenter des données dans le composant de requête.

Techniquement, la RFC 3976-3.4 définit le composant de requête comme:

query       = *( pchar / "/" / "?" )

Cette syntaxe signifie que la requête peut inclure tous les caractères de pchar ainsi que / et ?. pchar fait référence à une autre spécification de caractères de chemin. Utilement, Annexe A de la RFC 3986 répertorie les définitions ABNF pertinentes, notamment:

query         = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Ainsi, en plus de tous alphanumériques et pourcentages de caractères codés , une requête peut légalement inclure les caractères non codés suivants:

/ ? : @ - . _ ~ ! $ & ' ( ) * + , ; =

Bien sûr, vous souhaiterez peut-être garder à l'esprit que "=" et "&" ont généralement une signification particulière dans une requête.

42
PJ King