Quand coder l'espace en plus (+) ou% 20?

487

Parfois, les espaces reçoivent une URL codée pour le +signe, d'autres fois pour %20. Quelle est la différence et pourquoi cela devrait-il se produire?

Muhammad Hewedy
la source
11
doublon possible de l' URL codant le caractère espace: + ou% 20?
Cole Johnson

Réponses:

481

+signifie un espace uniquement dans le application/x-www-form-urlencodedcontenu, tel que la partie requête d'une URL:

http://www.example.com/path/foo+bar/path?query+name=query+value

Dans cette URL, le nom du paramètre est query nameun espace et la valeur est query valueun espace, mais le nom du dossier dans le chemin est littéralement foo+bar, non foo bar .

%20est un moyen valide pour encoder un espace dans l'un ou l'autre de ces contextes. Donc, si vous devez encoder une chaîne URL pour l'inclure dans une partie d'une URL, il est toujours sûr de remplacer les espaces par %20et les points positifs avec %2B. C'est ce que, par exemple. encodeURIComponent()fait en JavaScript. Malheureusement, ce n'est pas ce que fait urlencode en PHP (le rawurlencode est plus sûr).

Voir aussi Application de spécification HTML 4.01 / x-www-form-urlencoded

bobince
la source
5
vraiment je suis confus, ma question est, quand le navigateur fait le premier formulaire, et quand le deuxième fomr?
Muhammad Hewedy
11
Le navigateur créera un query+name=query+valueparamètre à partir d'un formulaire avec <input name="query name" value="query value">. Il ne créera pas à query%20namepartir d'un formulaire, mais il est totalement sûr de l'utiliser à la place, par exemple. si vous assemblez vous-même un formulaire pour un XMLHttpRequest. Si vous avez une URL avec un espace, comme <a href="http://www.example.com/foo bar/">, alors le navigateur le codera %20pour que vous corrigiez votre erreur, mais il est préférable de ne pas s'y fier.
bobince
6
quelle fonction javascript sur faire foo barpour foo+bar?
Sisir
21
@Sisir: il n'y a pas de fonction JS qui fera l'encodage sous forme d'URL. Vous pouvez naturellement le faire encodeURIComponent(s).replace(/%20/g, '+')si vous en avez vraiment besoin+
bobince
2
C'est un exemple très, très déroutant de quelque chose qui est codé en forme d'url. Cela n'a rien à voir avec les URL.
Dave Van den Eynde
54

http://www.example.com/some/path/to/resource?param1=value1

La partie avant le point d'interrogation doit utiliser% encoding (donc %20pour l'espace), après le point d'interrogation, vous pouvez utiliser soit %20ou +pour un espace. Si vous avez besoin d'un réel +après l'utilisation du point d'interrogation %2B.

cerberos
la source
6
@DaveVandenEynde Pourquoi pas?
cerberos
10
parce que c'est faux. Cela fait partie de l'ancien type de média application / x-www-form-urlencoded qui ne s'applique pas aux URL. En outre, decodeURIComponentne pas le décoder.
Dave Van den Eynde
3
Oui, il est probablement copié à partir de RFC 1630 et n'a jamais vraiment été une norme. tools.ietf.org/html/rfc3986 est la norme (mise à jour à nouveau pour IPv6 ou quelque chose). Bien sûr, les navigateurs le "soutiennent" mais qu'est-ce que cela signifie? C'est le code serveur ou client qui lit la chaîne de requête et la décode, pas le navigateur. Le navigateur le passe simplement d'avant en arrière, et comme il +s'agit d'un caractère réservé, il sera conservé par le navigateur.
Dave Van den Eynde
18
Google utilise les + pour les espaces dans ses URL de recherche ( google.com/#q=perl+equivalent+to+php+urlencode+spaces+as+%2B ).
Justin
2
FYI: Rails décode également les espaces avec +par défaut ( { foo: 'bar bar'}.to_query=> foo=bar+bar)
wrtsprt
46

Donc, les réponses ici sont toutes un peu incomplètes. L'utilisation d'un «% 20» pour coder un espace dans les URL est explicitement définie dans RFC3986 , qui définit la façon dont un URI est construit. Il n'y a aucune mention dans cette spécification de l'utilisation d'un '+' pour l'encodage des espaces - si vous vous en tenez uniquement à cette spécification, un espace doit être encodé en tant que '% 20'.

La mention de l'utilisation du «+» pour l'encodage des espaces provient des différentes incarnations de la spécification HTML - en particulier dans la section décrivant le type de contenu «application / x-www-form-urlencoded». Il est utilisé pour publier des données de formulaire.

Maintenant, la spécification HTML 2.0 (RFC1866) dit explicitement, dans la section 8.2.2, que la partie Query de la chaîne URL d'une demande GET doit être codée comme 'application / x-www-form-urlencoded'. Ceci, en théorie, suggère qu'il est légal d'utiliser un «+» dans l'URL dans la chaîne de requête (après le «?»).

Mais ... le fait-il vraiment? N'oubliez pas que HTML est en soi une spécification de contenu et que les URL avec des chaînes de requête peuvent être utilisées avec du contenu autre que HTML. De plus, bien que les versions ultérieures de la spécification HTML continuent de définir «+» comme légal dans le contenu «application / x-www-form-urlencoded», elles omettent complètement la partie indiquant que les chaînes de requête de requête GET sont définies comme ce type. Il n'y a, en fait, aucune mention du codage de la chaîne de requête dans quoi que ce soit après la spécification HTML 2.0.

Ce qui nous laisse avec la question - est-ce valable? Il y a certainement BEAUCOUP de code hérité qui prend en charge '+' dans les chaînes de requête, et beaucoup de code qui le génère également. Les chances sont donc bonnes, vous ne casserez pas si vous utilisez '+'. (Et, en fait, j'ai fait toutes les recherches à ce sujet récemment parce que j'ai découvert un site majeur qui n'a pas accepté «% 20» dans une requête GET en tant qu'espace. Ils n'ont en fait décodé AUCUN pourcentage de caractères encodés. Donc, le service que vous réutiliser peut également être pertinent.)

Mais à partir d'une lecture pure des spécifications, sans que le langage de la spécification HTML 2.0 ne soit repris dans les versions ultérieures, les URL sont entièrement couvertes par RFC3986, ce qui signifie que les espaces doivent être convertis en '% 20'. Et cela devrait certainement être le cas si vous demandez autre chose qu'un document HTML.

zgwortz
la source
Pour ajouter à votre réponse, Chrome code par défaut les espaces dans les URL sous la forme %20( <a href="?q=a b">), mais lorsque vous envoyez un formulaire, il utilise le +signe. Vous pouvez remplacer cela en utilisant explicitement le +signe ( <a href="?q=a+b">) ou en envoyant le formulaire à l'aide de XMLHTTPRequest.
x-yuri
Il est vraiment difficile de comprendre le but de l'ajout d'URLSearchParams developers.google.com/web/updates/2016/01/urlsearchparams , qui fonctionne d'une manière ancienne (sérialiser SPACE en «+»). Il n'est même pas pris en charge dans IE11!
Nymphétamine
9

Il vaut mieux toujours encoder les espaces en% 20, pas en "+".

Il s'agissait de la RFC-1866 (spécification HTML 2.0), qui spécifiait que les caractères d'espace devaient être codés en "+" dans les paires clé-valeur de type de contenu "application / x-www-form-urlencoded". (voir paragraphe 8.2.1. alinéa 1.). Cette façon d'encoder les données du formulaire est également donnée dans les spécifications HTML ultérieures, recherchez les paragraphes pertinents sur application / x-www-form-urlencoded.

Voici un exemple d'une telle chaîne dans l'URL où la RFC-1866 autorise le codage des espaces comme avantages: "http://example.com/over/there?name=foo+bar". Ainsi, seulement après "?", Les espaces peuvent être remplacés par des points positifs, selon la RFC-1866. Dans d'autres cas, les espaces doivent être codés en% 20. Mais comme il est difficile de déterminer le contexte, il est préférable de ne jamais coder les espaces en "+".

Je recommanderais de coder en pourcentage tous les caractères sauf "non réservé" défini dans RFC-3986, p.2.3

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
Maxim Masiutin
la source
1
Dans .Net Framework, UrlEncode utilise '+' dans QueryString, mais dans .Net Core% 20 moderne est utilisé
Michael Freidgeim
@ MiFreidgeimSO-stopbeingevil Merci de nous en informer. Il semble que le .Net Core moderne ait décidé d'être plus cohérent et compatible.
Maxim Masiutin
2

Quelle est la différence: voir les autres réponses.

Quand utiliser +au lieu de %20? À utiliser +si, pour une raison quelconque, vous souhaitez rendre la chaîne de requête URL ( ?.....) ou le fragment de hachage ( #....) plus lisible. Exemple: vous pouvez réellement lire ceci:

https://www.google.se/#q=google+doesn%27t+encode+:+and+uses+%2B+instead+of+spaces ( %2B= +)

Mais ce qui suit est beaucoup plus difficile à lire: (au moins pour moi)

https://www.google.se/#q=google%20doesn%27t%20oops%20:%20%20this%20text%20%2B%20is%20different%20spaces

Je pense qu'il +est peu probable de casser quoi que ce soit, car Google utilise +(voir le premier lien ci-dessus) et ils y ont probablement pensé. Je vais +m'utiliser juste parce que lisible + Google pense que c'est OK.

KajMagnus
la source
7
Je dis que l'argument de «lisibilité» est la meilleure défense pour «+». L'argument "google does it" est fallacieux en.wikipedia.org/wiki/Argument_from_authority
FlipMcF
2
@FlipMcF La page Wikipédia fallacieuse de l'argument de l'autorité concerne "lorsqu'une autorité est citée sur un sujet en dehors de son domaine d'expertise ou lorsque l'autorité citée n'est pas un véritable expert " - je pense cependant que les ordinateurs, HTTP et URL l'encodage fait partie du domaine d'expertise de Google.
KajMagnus
3
@FlipMcF Le fait de citer le comportement de google, dans ce cas, est un argument valable pour utiliser "+" dans les URL. Ce n'est pas que Google soit une autorité, mais que Google est probablement la plus grande société Internet et s'ils font quelque chose, il est très peu probable que les navigateurs décident un jour de cesser de soutenir cette pratique. De plus, Google Chrome est l'un des navigateurs avec la part la plus élevée, et ils prendront en charge tout ce que Google voudra. Dans l'ensemble, je dirais que personne n'utilisant "+" au lieu de "% 20" n'aura de difficulté à cause de cela dans un avenir prévisible.
jdferreira
J'aimerais continuer cet argument ailleurs, où il y a un appel à la popularité pour refuser de reconnaître un appel à l'autorité. Au moins, nous pouvons tous nous mettre d'accord sur une chose: '+' est supérieur à '% 20'
FlipMcF
1
En fait, l'URL avec% 20 est beaucoup plus facile à lire car les navigateurs (de bureau) affichent l'URL décodée en bas de la fenêtre si vous déplacez le curseur de la souris sur le lien. Les signes plus sont affichés inchangés.
Martin