Un «+» dans un schéma d'URL / hôte / chemin représente-t-il un espace?

224

Je sais qu'un +dans la chaîne de requête d'une URL représente un espace. Est-ce également le cas en dehors de la région de chaîne de requête? C'est-à-dire, fait l'URL suivante:

http://a.com/a+b/c

représentent en fait:

http://a.com/a b/c

(et doivent donc être codés s'il doit en fait être un +), ou représente-t-il réellement a+b/c?

Francisco Ryan Tolmasky I
la source
4
Notez qu'en php, urldecode décode le% 2b (encodé +) en espace. Pour éviter cette utilisation rawurldecode. Je dis cela ici à titre de référence, car il s'agit d'un résultat très apprécié sur la recherche Google pour "les décodages d'URL php se cassent sur le symbole plus".
danielson317
1
Copie possible de Quand encoder l'espace en plus (+) ou% 20?
utilisateur

Réponses:

170
  • Le pourcentage d'encodage dans la section de chemin d'une URL devrait être décodé, mais
  • tous les +caractères du composant path doivent être traités littéralement.

Pour être explicite: +n'est qu'un caractère spécial dans le composant de requête.

Stobor
la source
12
+1 Malheureusement, de nombreux "codeurs / encodeurs d'URL" dans la nature ne comprennent pas cela. Par exemple sislands.com/coin70/week6/encoder.htm keyone.co.uk/tools-url-encoder.asp meyerweb.com/eric/tools/dencoder
leonbloy
11
@Stobor: citation nécessaire.
bukzor
8
@Stobor La RFC a-t-elle déjà indiqué que le +caractère est interprété comme un espace dans le composant de requête? Ou s'agit-il simplement d'une règle «sauvage»?
Pacerier
44
@Pacerier et @bukzor: la RFC 1738 (telle que modifiée par 2396 et 3986) définit le composant schéma ( http:), autorité ( //server.example.com) et chemin ( /myfile/mypage.htm) et ne définit aucune signification particulière pour le +caractère. La spécification HTML définit le composant de requête comme étant de type mime application / x-www-form-urlencoded qui est défini comme "remplacer les espaces par +et d'autres caractères spéciaux comme dans RFC1738". Il ne s'agit donc pas «de la nature», mais d'une norme acceptée (non RFC).
Stobor
2
La méthode .NET Server.UrlEncodecode à tort les espaces en tant que points positifs dans la partie chemin d'accès, violant ainsi les règles HTTP.
Suncat2000
243

Vous pouvez trouver une belle liste de caractères codés URL correspondants sur W3Schools .

  • + devient %2B
  • l'espace devient %20
Niels R.
la source
18
Il est parfaitement légal que les caractères littéraux «+» apparaissent dans le composant path sur une URL.
Sam Stainsby
4
Pour qu'un littéral + soit reçu par le back-end (ou, au moins PHP), il doit être codé en triple:%25252B
Umbrella
11
Cette réponse n'a aucun rapport avec la question.
Nisse Engström
22

Les caractères d'espace ne peuvent être codés que "+" dans un seul contexte: paires clé-valeur application / x-www-form-urlencoded.

RFC-1866 (spécification HTML 2.0), paragraphe 8.2.1. le sous-paragraphe 1. dit: "Les noms et valeurs des champs du formulaire sont échappés: les caractères d'espace sont remplacés par" + ", puis les caractères réservés sont échappés").

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 (dans d'autres cas, les espaces doivent être codés en% 20). Cette méthode de codage des données de formulaire est également indiqué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.

Mais, comme il est difficile de toujours déterminer correctement le contexte, il est préférable de ne jamais coder les espaces en "+". Il est préférable de coder en pourcentage tous les caractères sauf "non réservé" défini dans RFC-3986, p.2.3. Voici un exemple de code qui illustre ce qui doit être encodé. Il est donné en langage de programmation Delphi (pascal), mais il est très facile de comprendre comment il fonctionne pour n'importe quel programmeur quel que soit le langage possédé:

(* percent-encode all unreserved characters as defined in RFC-3986, p.2.3 *)
function UrlEncodeRfcA(const S: AnsiString): AnsiString;
const    
  HexCharArrA: array [0..15] of AnsiChar = '0123456789ABCDEF';
var
  I: Integer;
  c: AnsiChar;
begin
 // percent-encoding, see RFC-3986, p. 2.1
  Result := S;
  for I := Length(S) downto 1 do
  begin
    c := S[I];
    case c of
      'A' .. 'Z', 'a' .. 'z', // alpha
      '0' .. '9',             // digit
      '-', '.', '_', '~':;    // rest of unreserved characters as defined in the RFC-3986, p.2.3
      else
        begin
          Result[I] := '%';
          Insert('00', Result, I + 1);
          Result[I + 1] := HexCharArrA[(Byte(C) shr 4) and $F)];
          Result[I + 2] := HexCharArrA[Byte(C) and $F];
        end;
    end;
  end;
end;

function UrlEncodeRfcW(const S: UnicodeString): AnsiString;
begin
  Result := UrlEncodeRfcA(Utf8Encode(S));
end;
Maxim Masiutin
la source
0

utilisez la fonction encodeURIComponent pour corriger l'url, cela fonctionne sur le navigateur et node.js

res.redirect("/signin?email="+encodeURIComponent("[email protected]"));


> encodeURIComponent("http://a.com/a+b/c")
'http%3A%2F%2Fa.com%2Fa%2Bb%2Fc'
Baryon Lee
la source
1
Cela ne règle pas la question. Et, code incorrectement les URL, avec une langue spécifique (JavaScript) - selon le contexte, vous ne voulez probablement pas coder là où vous avez besoin de barres obliques (/) et de deux-points (:) non spécifiques (:) pour que l'URL fonctionne .
Gremio
Merci, ça m'a vraiment aidé!
qwsd
-2

Essayez ci-dessous:

<script type="text/javascript">

function resetPassword() {
   url: "submitForgotPassword.html?email="+fixEscape(Stringwith+char);
}
function fixEscape(str)
{
    return escape(str).replace( "+", "%2B" );
}
</script>
The Java Guy
la source
2
Je trouve très étrange que deux personnes aient voté pour cette réponse. Cela n'a littéralement rien à voir avec la question.
Andrew Barber
1
Et pour les autres personnages * @ - _ +. /
Ravi
1
@AndrewBarber Pourquoi avez-vous trouvé cela non pertinent? + devient% 2B
The Java Guy
C'est faux pour tant de raisons ... escapeest déconseillé, à la place, vous devez utiliser encodeURIou dans le cas de la partie de requête encodeURIComponent. La chaîne de paramètres doit également être codée conformément à w3c .
Christoph
-5

Tu coderas toujours les URL.

Voici comment Ruby code votre URL:

irb(main):008:0> CGI.escape "a.com/a+b"
=> "a.com%2Fa%2Bb"
Lennart Koopmann
la source
8
Je ne suis pas sûr que ce soit vrai. Selon RFC2396 ( ietf.org/rfc/rfc2396.txt ), les plus ne sont pas des caractères réservés dans le chemin (segments) de l'URI, uniquement le composant de requête. Cela semble impliquer qu'ils n'ont pas besoin d'être encodés en URL et ne doivent donc pas être interprétés comme des espaces dans le chemin, uniquement dans la requête.
tlrobinson
3
rfc 1738 traite cependant les avantages comme des espaces. Tout dépend de ce qui est implémenté par vos fonctions d'encodage / décodage. par exemple, en php, rawurlencode suit rfc 1738 tandis que urlencode suit rfc 2396.
Jonathan Fingland
1
Vous voyez, maintenant j'ai une confusion supplémentaire. Dans l'exemple que vous m'avez donné ci-dessus, a.com% 2Fa% 2Bb n'est pas ce que je veux, ce serait à tout le moins a.com/a%2Bb. Il s'agit d'une URL réelle que je traite, pas d'une URL transmise en tant que paramètre dans une chaîne de requête. Pour un petit arrière-plan qui peut aider à clarifier, le Finder de Mac OS X me renvoie des URL de système de fichiers. Donc, si j'ai un fichier nommé "a? + B.txt", il renvoie quelque chose qui ressemble à "fichier: //a%3F+b.txt", PAS "fichier: //a%3F%2B.txt" . Le viseur est-il juste incorrect, ou un + avant que la chaîne de requête soit-il réellement un plus?
Francisco Ryan Tolmasky I
2
Jonathan: Êtes-vous sûr que 1738 indique + est réservé? Je vois: safe = "$" | "-" | "_" | "." | "+" non réservé = alpha | chiffre | sûr | extra ainsi que: Ainsi, seuls les caractères alphanumériques, les caractères spéciaux "$ -_. +! * '()" et les caractères réservés utilisés à leurs fins réservées peuvent être utilisés non codés dans une URL.
tlrobinson
2
"Tu échapperas toujours" a besoin de plus de nuances, et la réponse est de toute façon sans rapport avec la question.
bug