web-dev-qa-db-fra.com

URL encodant le caractère d'espace: + ou% 20?

Quand un espace dans une URL est-il codé en + et quand est-il codé en %20?

657
BC.

De Wikipedia (accentuation et lien ajoutés):

Lorsque les données saisies dans les formulaires HTML sont soumises, les noms et les valeurs de champs de formulaire sont codés et envoyés au serveur dans un message de requête HTTP à l'aide de la méthode GET ou POST, ou, historiquement, par courrier électronique. Le codage utilisé par défaut est basé sur une version très ancienne des règles générales de codage d'URI, avec un nombre de modifications tel que la normalisation de la nouvelle ligne et le remplacement des espaces par "+" au lieu de "% 20". Le type de données MIME codé de cette manière est application/x-www-form-urlencoded, et il est actuellement défini (toujours de manière très obsolète). ) dans les spécifications HTML et XForms.

Ainsi, le réel pourcentage encodage utilise %20 tandis que les données de formulaire dans les URL sont sous une forme modifiée qui utilise +. Il est donc plus probable que vous ne voyiez que + dans les URL de la chaîne de requête après un ?.

386
Joey

Cette confusion est due au fait que les URL sont encore "brisées" à ce jour.

Prenez " http://www.google.com " par exemple. Ceci est une URL. Une URL est un localisateur de ressources uniforme et est en réalité un pointeur sur une page Web (dans la plupart des cas). Les URL ont en fait une structure très bien définie depuis la première spécification de 1994.

Nous pouvons extraire des informations détaillées sur l'URL " http://www.google.com ":

+---------------+-------------------+
|      Part     |      Data         |
+---------------+-------------------+
|  Scheme       | http              |
|  Host         | www.google.com    |
+---------------+-------------------+

Si nous regardons une URL plus complexe telle que:

" https: // bob: [email protected]: 8080/file; p = 1? q = 2 # tiers "

nous pouvons extraire les informations suivantes:

+-------------------+---------------------+
|        Part       |       Data          |
+-------------------+---------------------+
|  Scheme           | https               |
|  User             | bob                 |
|  Password         | bobby               |
|  Host             | www.lunatech.com    |
|  Port             | 8080                |
|  Path             | /file;p=1           |
|  Path parameter   | p=1                 |
|  Query            | q=2                 |
|  Fragment         | third               |
+-------------------+---------------------+

https://bob:[email protected]:8080/file;p=1?q=2#third
\___/   \_/ \___/ \______________/ \__/\_______/ \_/ \___/
  |      |    |          |          |      | \_/  |    |
Scheme User Password    Host       Port  Path |   | Fragment
        \_____________________________/       | Query
                       |               Path parameter
                   Authority

Les caractères réservés sont différents pour chaque partie.

Pour les URL HTTP, un espace dans une partie de fragment de chemin doit être codé en "% 20" (pas, absolument pas "+"), tandis que le caractère "+" dans la partie de fragment de chemin peut être laissé non codé.

Désormais, dans la partie requête, les espaces peuvent être codés avec "+" (pour des raisons de compatibilité ascendante: n'essayez pas de le rechercher dans le standard URI) ou avec "% 20" tandis que le caractère "+" (en raison de cette ambiguïté). ) doit être échappé à "% 2B".

Cela signifie que la chaîne "blue + light blue" doit être codée différemment dans les éléments de chemin et de requête:

" http://example.com/blue+light%20blue?blue%2Blight+blue ".

De là, vous pouvez en déduire qu'il est impossible de coder une URL entièrement construite sans une connaissance syntaxique de la structure de l'URL.

Cela revient à:

Vous devriez avoir %20 avant le ? et + après.

Source

261
Matas Vaitkevicius

Je recommanderais %20.

Êtes-vous les coder en dur?

Ce n'est pas très cohérent dans les langues, cependant. Si je ne me trompe pas, dans PHP urlencode() traite les espaces comme + alors que Python urlencode() les traite comme %20.

MODIFIER:

Il semble que je me trompe. La urlencode() de Python (au moins en 2.7.2) utilise quote_plus() au lieu de quote() et code ainsi les espaces comme "+". Il semble également que la recommandation du W3C soit le "+" comme indiqué ici: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

Et en fait, vous pouvez suivre ce débat intéressant sur le propre système de suivi des problèmes de Python sur ce qu'il faut utiliser pour encoder les espaces: http://bugs.python.org/issue13866 .

EDIT # 2:

Je comprends que le moyen le plus courant d’encoder "" est le "+", mais juste une note, c’est peut-être juste moi, mais je trouve cela un peu déroutant:

import urllib
print(urllib.urlencode({' ' : '+ '})

>>> '+=%2B+'
24
Rui Vieira

Un espace ne peut être encodé qu'en "+" dans la partie de requête d'une paire clé-valeur de type de contenu "application/x-www-form-urlencoded" d'une URL. À mon avis, ceci est un MAI, pas un MUST. Dans le reste des URL, il est codé sous la forme% 20.

À mon avis, il est préférable de toujours coder les espaces en tant que% 20, et non en tant que "+", même dans la partie requête d'une URL, car c'est la spécification HTML (RFC-1866) qui spécifie que les espaces doivent être codés comme " + "dans" application/x-www-form-urlencoded ", paires contenu-type contenu-type (voir paragraphe 8.2.1. sous-paragraphe 1.)

Cette manière de coder les données de formulaire est également donnée dans les spécifications HTML ultérieures. Par exemple, recherchez les paragraphes pertinents sur application/x-www-form-urlencoded dans la spécification HTML 4.01, etc.

Voici un exemple de chaîne dans l'URL où la spécification HTML autorise le codage des espaces comme des atouts: " http://example.com/over/there?name=foo+bar ". Donc, seulement après "?", Les espaces peuvent être remplacés par des plus . Dans les autres cas, les espaces doivent être codés en% 20. Mais comme il est difficile de déterminer correctement le contexte, il est recommandé de ne jamais coder les espaces en tant que "+".

Je recommanderais d'encoder tous les caractères, sauf "sans réserve" défini dans RFC-3986, p.2.3

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

L'implémentation dépend du langage de programmation choisi.

Si votre URL contient des caractères nationaux, commencez par les encoder en UTF-8, puis encodez le résultat en pourcentage.

11
Maxim Masiutin