Un `+` in uno schema URL / host / percorso rappresenta uno spazio?


224

Sono consapevole che +nella stringa di query di un URL rappresenta uno spazio. Questo vale anche al di fuori dell'area della stringa di query? Vale a dire, fa il seguente URL:

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

in realtà rappresentano:

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

(e quindi deve essere codificato se dovrebbe effettivamente essere un +), o in realtà rappresenta effettivamente a+b/c?



4
Si noti che in php urldecode decodifica% 2b (codificato +) in uno spazio. Per evitare questo uso rawurldecode. Lo dico qui come riferimento perché questo è un risultato molto apprezzato nella ricerca su Google per "interruzioni di decodifica php url sul simbolo più".
danielson317

Risposte:


170
  • La codifica percentuale nella sezione del percorso di un URL dovrebbe essere decodificata, tuttavia
  • tutti i +caratteri nel componente path devono essere trattati alla lettera.

Per essere espliciti: +è solo un carattere speciale nel componente della query.


12
+1 Sfortunatamente, molti "codificatori / codificatori di URL" là fuori in natura non lo capiscono. Ad esempio, sislands.com/coin70/week6/encoder.htm keyone.co.uk/tools-url-encoder.asp meyerweb.com/eric/tools/dencoder
leonbloy

11
@Stobor: citazione necessaria.
Bukzor,

8
@Stobor L'RFC ha mai affermato che il +carattere è interpretato come uno spazio nel componente della query? O è semplicemente una regola "dal selvaggio"?
Pacerier

44
@Pacerier e @bukzor: RFC 1738 (modificato da 2396 e 3986) definisce i componenti schema ( http:), autorità ( //server.example.com) e percorso ( /myfile/mypage.htm) e non definisce alcun significato speciale per il +carattere. Le specifiche HTML definiscono il componente della query come mime type application / x-www-form-urlencoded che è definito come "sostituisci gli spazi con +e altri caratteri speciali come in RFC1738". Quindi non è "dal selvaggio", ma da uno standard accettato (non RFC).
Stobor,

2
Il metodo .NET Server.UrlEncodecodifica erroneamente anche gli spazi come aspetti nella parte del percorso, violando le regole HTTP.
Suncat2000,

243

Puoi trovare un buon elenco di caratteri codificati URL corrispondenti su W3Schools .

  • + diventa %2B
  • lo spazio diventa %20

18
È perfettamente legale che i caratteri '+' letterali vengano visualizzati nel componente path su un URL.
Sam Stainsby,

4
Per ottenere un + letterale da ricevere dal back-end (o, almeno, PHP), deve essere triplo codificato:%25252B
Umbrella,

11
Questa risposta è completamente irrilevante per la domanda.
Nisse Engström,

22

I caratteri spaziali possono essere codificati come "+" in un unico contesto: coppie chiave-valore codificate application / x-www-form-urlencoded.

RFC-1866 (specifica HTML 2.0), paragrafo 8.2.1. il sottoparagrafo 1. dice: "I nomi e i valori dei campi del modulo sono sfuggiti: i caratteri di spazio sono sostituiti da` + 'e quindi i caratteri riservati sono sfuggiti ").

Ecco un esempio di tale stringa nell'URL in cui RFC-1866 consente la codifica di spazi come vantaggi: " http://example.com/over/there?name=foo+bar ". Quindi, solo dopo "?", Gli spazi possono essere sostituiti da vantaggi (in altri casi, gli spazi devono essere codificati in% 20). Questo modo di codificare i dati dei moduli viene anche fornito nelle specifiche HTML successive, ad esempio, cercare i paragrafi pertinenti sull'applicazione / x-www-form-urlencoded nelle specifiche HTML 4.01 e così via.

Tuttavia, poiché è difficile determinare sempre correttamente il contesto, è consigliabile non codificare mai gli spazi come "+". È meglio codificare in percentuale tutti i caratteri tranne "senza prenotazione" definito in RFC-3986, p. 2.3. Ecco un esempio di codice che illustra cosa dovrebbe essere codificato. Viene fornito nel linguaggio di programmazione Delphi (pascal), ma è molto facile capire come funziona per qualsiasi programmatore indipendentemente dal linguaggio posseduto:

(* 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;

0

usa la funzione encodeURIComponent per correggere l'URL, funziona su Browser e node.js

res.redirect("/signin?email="+encodeURIComponent("aaa+bbb-ccc@example.com"));


> encodeURIComponent("http://a.com/a+b/c")
'http%3A%2F%2Fa.com%2Fa%2Bb%2Fc'

1
Questo non affronta la domanda. E, in modo errato codifica URL, con una lingua specifica (JavaScript) - a seconda del contesto, probabilmente non vuoi codificare dove hai bisogno di speciali (non letterali) barre (/) e due punti (:) per far funzionare l'URL .
Gremio,

Grazie mi ha davvero aiutato!
qwsd

-2

Prova di seguito:

<script type="text/javascript">

function resetPassword() {
   url: "submitForgotPassword.html?email="+fixEscape(Stringwith+char);
}
function fixEscape(str)
{
    return escape(str).replace( "+", "%2B" );
}
</script>

2
Trovo molto strano che due persone abbiano votato questa risposta. Non ha letteralmente nulla a che fare con la domanda.
Andrew Barber,

1
Che ne dici di altri personaggi * @ - _ +. /
Ravi

1
@AndrewBarber Perché l'hai trovato irrilevante? + diventa% 2B
The Java Guy

Questo è sbagliato per tanti motivi ... escapeè deprecato, invece dovresti usare encodeURIo nel caso della parte della query encodeURIComponent. Inoltre, la stringa del parametro deve essere codificata secondo w3c .
Christoph,

-5

Devi sempre codificare gli URL.

Ecco come Ruby codifica il tuo URL:

irb(main):008:0> CGI.escape "a.com/a+b"
=> "a.com%2Fa%2Bb"

8
Non sono sicuro che sia giusto. Secondo RFC2396 ( ietf.org/rfc/rfc2396.txt ) i caratteri non sono caratteri riservati nel percorso (segmenti) dell'URI, ma solo il componente della query. Ciò sembra implicare che non devono essere codificati in URL e quindi non devono essere interpretati come spazi nel percorso, ma solo nella query.
tlrobinson,

3
rfc 1738 tuttavia considera i plus come spazi. Tutto dipende da quale è implementato dalle funzioni di codifica / decodifica. per esempio, in php, rawurlencode segue rfc 1738 mentre urlencode segue rfc 2396.
Jonathan Fingland,

1
Vedi, ora ho qualche confusione aggiuntiva. Nell'esempio che mi hai dato sopra, a.com% 2Fa% 2Bb non è quello che voglio, sarebbe almeno a.com/a%2Bb. Questo è un URL reale con cui ho a che fare, non un URL passato come parametro in una stringa di query. Per alcuni retroscena che potrebbero aiutare a chiarire, il Finder di Mac OS X mi sta restituendo gli URL del file system. Quindi, se ho un file chiamato "a? + B.txt", restituisce qualcosa che assomiglia a "file: //a%3F+b.txt", NON "file: //a%3F%2B.txt" . Il finder è semplicemente errato o un + prima della stringa di query è in realtà un plus?
Francisco Ryan Tolmasky I,

2
Jonathan: Sei sicuro che il 1738 dice + è riservato? Vedo: safe = "$" | "-" | "_" | "" | "+" senza prenotazione = alfa | cifra | sicuro | extra oltre a: Pertanto, solo i caratteri alfanumerici, i caratteri speciali "$ -_. +! * '()," e i caratteri riservati utilizzati per i loro scopi riservati possono essere utilizzati non codificati all'interno di un URL.
tlrobinson,

2
"Devi sempre scappare" ha bisogno di più qualifiche e la risposta è comunque irrilevante per la domanda.
bug
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.