Stellt ein "+" in einem URL-Schema / Host / Pfad ein Leerzeichen dar?

224

Mir ist bekannt, dass ein +in der Abfragezeichenfolge einer URL ein Leerzeichen darstellt. Ist dies auch außerhalb des Abfragezeichenfolgenbereichs der Fall? Das heißt, tut die folgende URL:

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

tatsächlich darstellen:

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

(und müssen daher codiert werden, wenn es tatsächlich ein sein sollte +), oder repräsentiert es tatsächlich a+b/c?

Francisco Ryan Tolmasky I.
quelle
4
Beachten Sie, dass in PHP URL-Code% 2b (codiert +) in ein Leerzeichen decodiert. Um diese Verwendung zu vermeiden rawurldecode. Ich sage dies hier als Referenz, weil dies ein hoch bewertetes Ergebnis bei der Google-Suche nach "PHP-URL-Dekodierungsunterbrechungen bei Plus-Symbol" ist.
Danielson317

Antworten:

170
  • Es wird erwartet, dass die prozentuale Codierung im Pfadabschnitt einer URL dekodiert wird
  • Es +wird erwartet, dass alle Zeichen in der Pfadkomponente wörtlich behandelt werden.

Um es explizit zu sagen: +ist nur ein Sonderzeichen in der Abfragekomponente.

Stobor
quelle
12
+1 Leider verstehen viele "URL-Codierer / Encoder" in freier Wildbahn dies nicht. ZB sislands.com/coin70/week6/encoder.htm keyone.co.uk/tools-url-encoder.asp meyerweb.com/eric/tools/dencoder
leonbloy
11
@Stobor: Zitat erforderlich.
Bukzor
8
@Stobor Hat der RFC jemals angegeben, dass das +Zeichen als Leerzeichen in der Abfragekomponente interpretiert wird? Oder ist es einfach eine Regel "aus der Wildnis"?
Pacerier
44
@Pacerier und @bukzor: RFC 1738 (geändert durch 2396 und 3986) definiert die Komponenten Schema ( http:), Autorität ( //server.example.com) und Pfad ( /myfile/mypage.htm) und definiert keine spezielle Bedeutung für das +Zeichen. Die HTML-Spezifikation definiert die Abfragekomponente als MIME- Typ application / x-www-form-urlencoded, die als "Leerzeichen durch +und andere Sonderzeichen wie in RFC1738 ersetzen" definiert ist. Es ist also nicht "aus der Wildnis", sondern aus einem akzeptierten (Nicht-RFC-) Standard.
Stobor
2
Die .NET-Methode Server.UrlEncodecodiert fälschlicherweise Leerzeichen als Plusses im Pfadabschnitt, was gegen HTTP-Regeln verstößt.
Suncat2000
243

Auf W3Schools finden Sie eine schöne Liste der entsprechenden URL-codierten Zeichen .

  • + wird %2B
  • Raum wird %20
Niels R.
quelle
18
Es ist völlig legal, dass wörtliche '+' - Zeichen in der Pfadkomponente einer URL erscheinen.
Sam Stainsby
4
Um ein Literal + vom %25252B
Umbrella
11
Diese Antwort ist für die Frage völlig irrelevant.
Nisse Engström
22

Leerzeichen dürfen nur in einem Kontext als "+" codiert werden: application / x-www-form-urlencodierte Schlüssel-Wert-Paare.

Der RFC-1866 (HTML 2.0-Spezifikation), Absatz 8.2.1. In Unterabsatz 1 heißt es: "Die Formularfeldnamen und -werte werden maskiert: Leerzeichen werden durch" + "ersetzt, und dann werden reservierte Zeichen maskiert").

Hier ist ein Beispiel für eine solche Zeichenfolge in einer URL, in der RFC-1866 das Codieren von Leerzeichen als Pluspunkte zulässt: " http://example.com/over/there?name=foo+bar ". Leerzeichen können also erst nach "?" Durch Pluszeichen ersetzt werden (in anderen Fällen sollten Leerzeichen in% 20 codiert werden). Diese Art der Codierung von Formulardaten wird auch in späteren HTML-Spezifikationen angegeben. Suchen Sie beispielsweise nach relevanten Absätzen zu application / x-www-form-urlencoded in der HTML 4.01-Spezifikation usw.

Da es jedoch schwierig ist, den Kontext immer korrekt zu bestimmen, empfiehlt es sich, Leerzeichen niemals als "+" zu codieren. Es ist besser, alle Zeichen mit Ausnahme von "nicht reserviert", wie in RFC-3986, S. 2.3 definiert, prozentual zu codieren. Hier ist ein Codebeispiel, das zeigt, was codiert werden soll. Es wird in der Programmiersprache Delphi (Pascal) gegeben, aber es ist sehr leicht zu verstehen, wie es für jeden Programmierer funktioniert, unabhängig von der Sprache, die er besitzt:

(* 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
quelle
0

Verwenden Sie die Funktion encodeURIComponent, um die URL zu korrigieren. Sie funktioniert in Browser und 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
quelle
1
Dies geht nicht auf die Frage ein. Und codiert URLs falsch mit einer bestimmten Sprache (JavaScript) - je nach Kontext möchten Sie wahrscheinlich nicht codieren, wo Sie spezielle (nicht wörtliche) Schrägstriche (/) und Doppelpunkte (:) benötigen, damit die URL funktioniert .
Gremio
Danke, es hat mir wirklich geholfen!
Qwsd
-2

Versuchen Sie es unten:

<script type="text/javascript">

function resetPassword() {
   url: "submitForgotPassword.html?email="+fixEscape(Stringwith+char);
}
function fixEscape(str)
{
    return escape(str).replace( "+", "%2B" );
}
</script>
Der Java-Typ
quelle
2
Ich finde es sehr seltsam, dass zwei Personen diese Antwort gewählt haben. Es hat buchstäblich nichts mit der Frage zu tun.
Andrew Barber
1
Wie wäre es mit anderen Zeichen * @ - _ +. /
Ravi
1
@ AndrewBarber Warum fandest du es irrelevant? + wird% 2B
The Java Guy
Dies ist aus so vielen Gründen falsch ... escapeist veraltet, stattdessen sollten Sie encodeURIoder im Falle des Abfrageteils verwenden encodeURIComponent. Auch die Parameterzeichenfolge sollte gemäß w3c codieren .
Christoph
-5

Du sollst immer URLs verschlüsseln.

So codiert Ruby Ihre URL:

irb(main):008:0> CGI.escape "a.com/a+b"
=> "a.com%2Fa%2Bb"
Lennart Koopmann
quelle
8
Ich bin mir nicht sicher, ob das richtig ist. Gemäß RFC2396 ( ietf.org/rfc/rfc2396.txt ) sind Plusses keine reservierten Zeichen im Pfad (Segmente) des URI, sondern nur die Abfragekomponente. Dies scheint zu implizieren, dass sie nicht URL-codiert sein müssen und daher nicht als Leerzeichen im Pfad, sondern nur in der Abfrage interpretiert werden sollten.
Tlrobinson
3
RFC 1738 behandelt Pluspunkte jedoch als Leerzeichen. Es hängt alles davon ab, was von Ihren Codierungs- / Decodierungsfunktionen implementiert wird. Zum Beispiel folgt in PHP der Rawurlencode dem RFC 1738, während der Urlencode dem RFC 2396 folgt.
Jonathan Fingland
1
Sehen Sie, jetzt habe ich einige zusätzliche Verwirrung. In dem Beispiel, das Sie mir oben gegeben haben, ist a.com% 2Fa% 2Bb nicht das, was ich will, es wäre zumindest a.com/a%2Bb. Dies ist eine tatsächliche URL, mit der ich es zu tun habe, und keine URL, die als Parameter in einer Abfragezeichenfolge übergeben wird. Für einen kleinen Hintergrund, der zur Verdeutlichung beitragen kann, gibt der Mac OS X Finder Dateisystem-URLs an mich zurück. Wenn ich also eine Datei mit dem Namen "a? + B.txt" habe, wird etwas zurückgegeben, das wie "file: //a%3F+b.txt" aussieht, NICHT wie "file: //a%3F%2B.txt". . Ist der Finder einfach falsch oder ist ein + vor der Abfragezeichenfolge tatsächlich ein Plus?
Francisco Ryan Tolmasky I
2
Jonathan: Sind Sie sicher, dass 1738 sagt, dass + reserviert ist? Ich sehe: safe = "$" | "-" | "_" | "." | "+" uneingeschränkt = alpha | Ziffer | sicher | zusätzlich sowie: Daher dürfen nur alphanumerische Zeichen, die Sonderzeichen "$ -_. +! * '()" und reservierte Zeichen, die für ihre reservierten Zwecke verwendet werden, innerhalb einer URL unverschlüsselt verwendet werden.
Tlrobinson
2
"Du sollst immer entkommen" braucht mehr Qualifikation, und die Antwort ist für die Frage sowieso irrelevant.
Fehler