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.