2010-02-24 6 views
41

Questa domanda riguarda i caratteri nella parte della stringa di query dell'URL, che appaiono dopo il carattere del segno ?.Quali caratteri devono essere sfuggiti in una stringa di query HTTP?

Per Wikipedia, alcuni caratteri vengono sinistro e altri sono codificati (di solito con una sequenza % escape).

Ho cercato di rintracciarlo in base a specifiche effettive, in modo da comprendere la giustificazione dietro ogni punto elenco in quella pagina di Wikipedia.

Contraddizione Esempio 1:

La HTML specification dice allo spazio come codificare + e rinvia il resto a RFC1738. Tuttavia, questa RFC afferma che ~ non è sicuro e inoltre che "[tutti] i caratteri non sicuri devono sempre essere codificati all'interno dell'URL". Questo sembra contraddire Wikipedia.

In pratica, IE8 codifica ~ nelle stringhe di query che genera, mentre FF3 lo lascia così com'è.

Contraddizione Esempio 2:

Wikipedia afferma che tutti i caratteri che non menziona devono essere codificati. ! non è menzionato in Wikipedia. Ma RFC1738 afferma che ! è un carattere "speciale" e "può essere utilizzato non codificato". Questo sembra contraddire Wikipedia che dice che deve essere codificato.

In pratica, IE8 codifica ! nelle stringhe di query che genera, mentre FF3 lo lascia così com'è.

Capisco che la morale di questo sarà probabilmente quella di codificare quei personaggi che sono in dubbio tra Wikipedia e le specifiche. Forse arrivando addirittura a codificare tutto ciò che non è [A-Za-z0-9]. Vorrei solo conoscere gli standard attuali su questo.

Conclusioni

l'algoritmo descritto su Wikipedia codifica proprio quei personaggi che non sono RFC3986 unreserved characters. Cioè, codifica tutti i caratteri diversi da quelli alfanumerici e -._~. Come caso speciale, lo spazio è codificato come + anziché %20 per RFC3986.

Alcune applicazioni utilizzano un RFC meno recente. Per confronto, gli RFC2396 unreserved characters sono alfanumerici e !'()*-._~.

Per il confronto, lo HTML5 working draft algorithm codifica tutti i caratteri diversi da alfanumerici e *-._. La codifica del caso speciale per lo spazio rimane +. Differenze notevoli sono che * non è codificato e ~ è codificato. (Tecnicamente, questa gestione di * è compatibile con RFC3986 anche se * è in reserved perché è nel sub-delims che sono ammesso nel query produzione.)

+2

Wikipedia non è un organismo di normalizzazione. In caso di dubbio, utilizzare lo standard. –

+8

@John - anche se è importante utilizzare lo standard * correct *. Che è 3986, in questo caso, non è il più vecchio 1738. –

risposta

37

La risposta sta nel documento RFC 3986, specificamente Section 3.4.

La componente di query è indicato dalla prima domanda marchio ("?") Carattere e terminato da un simbolo di cancelletto ("#") carattere o entro la fine del URI.

...

I caratteri slash ("/") e il punto interrogativo ("?") Può rappresentare i dati all'interno del componente di query.

Tecnicamente, RFC 3976-3,4 definisce il componente query come:

query  = *(pchar/"/"/"?") 

Questa sintassi significa che query può includere tutti i caratteri da pchar nonché / e ?. pchar fa riferimento a un'altra specifica dei caratteri di percorso. Utilmente, Appendix A di RFC 3986 elenca le definizioni ABNF rilevanti, più in particolare:

query   = *(pchar/"/"/"?") 
pchar   = unreserved/pct-encoded/sub-delims/":"/"@" 
unreserved = ALPHA/DIGIT/"-"/"."/"_"/"~" 
pct-encoded = "%" HEXDIG HEXDIG 
sub-delims = "!"/"$"/"&"/"'"/"("/")"/"*"/"+"/","/";"/"=" 

Così, oltre a tutti i caratteri alfanumerici e caratteri percentuali codificati, una query può legalmente includere i seguenti caratteri in chiaro:

/ ? : @ - . _ ~ ! $ & ' () * + , ; = 

Naturalmente, si consiglia di tenere a mente che '=' e '&' di solito hanno un significato speciale all'interno di una query.

+2

Nota: oltre '=' e '&', serverside potrebbe limitare gli altri caratteri di stringa di query legalmente non codificata come '.' (dot) in PHP dove sarà sostituito da un' _' (carattere di sottolineatura) in '$ _GET' e' $ _POST'. Vedere: http://stackoverflow.com/questions/68651/get-php-to-stop-replacing-characters-in-get-or-post-arrays (ha anche una soluzione alternativa). – GitaarLAB