2009-05-26 24 views
96

Conosco lo schema% uxxxx non standard, ma non mi sembra una scelta saggia dal momento che lo schema è stato rifiutato dal W3C.Qual è il modo corretto per codificare URL caratteri Unicode?

Alcuni esempi interessanti:

Il carattere di cuore. Se scrivo questo nel mio browser:

http://www.google.com/search?q=♥ 

quindi copiare e incollare, vedo questo URL

http://www.google.com/search?q=%E2%99%A5 

che fa sembrare come Firefox (o Safari) sta facendo questo.

urllib.quote_plus(x.encode("latin-1")) 
'%E2%99%A5' 

che ha senso, tranne che per le cose che non possono essere codificate in Latin-1, come il carattere del punto triplo.

Se scriv l'URL

http://www.google.com/search?q=… 

nel mio browser quindi copiare e incollare, ottengo

http://www.google.com/search?q=%E2%80%A6 

indietro. Quale sembra essere il risultato di fare

urllib.quote_plus(x.encode("utf-8")) 

che ha senso poiché ... non può essere codificato con Latin-1.

Ma poi non mi è chiaro come il browser sa se decodificare con UTF-8 o Latin-1.

Dal momento che questo sembra essere ambiguo:

In [67]: u"…".encode('utf-8').decode('latin-1') 
Out[67]: u'\xc3\xa2\xc2\x80\xc2\xa6' 

opere, quindi non so come il browser capisce se per decodificare quello con UTF-8 o Latin-1.

Qual è la cosa giusta da fare con i caratteri speciali che devo trattare?

+16

Entrambi i tuoi esempi sono codificati come UTF-8. Il primo certamente non Latin-1, dato che è lungo tre byte ... –

+1

% E2% 99% A5 è esadecimale per i valori di byte di [il "vestito cuore nero" in UTF-8] (http: // www. ltg.ed.ac.uk/~richard/utf-8.cgi?input=E2+99+A5&mode=bytes). Quel cuore nero non fa parte del set di caratteri [Latin-1] (http://en.wikipedia.org/wiki/ISO/IEC_8859-1). –

+0

Per vedere in modo preciso come e cosa codifica un browser (e molte altre informazioni utili), utilizzare gli strumenti per sviluppatori incorporati nella maggior parte dei browser moderni o ottenere un debugger HTTP gratuito come [Fiddler] (http: //www.telerik .com/violinista). –

risposta

54

Vorrei sempre codificare in UTF-8. Dal Wikipedia page on percent encoding:

I generici mandati di sintassi URI che i nuovi schemi URI che prevedono la rappresentazione dei dati di caratteri in un URI deve, in effetti, rappresentare caratteri del set senza riserve senza traduzione, e dovrebbero convertire tutti gli altri caratteri a byte secondo UTF-8, quindi codifica in percentuale tali valori. Questo requisito è stato introdotto nel gennaio 2005 con la pubblicazione di RFC 3986. Gli schemi URI introdotti prima di questa data non sono interessati.

Sembra che perché c'erano altri modi accettati di fare la codifica URL in passato, i browser tentare diversi metodi di decodifica di un URI, ma se siete quello che fa la codifica si dovrebbe usare UTF-8.

+8

Anche UTF-8 dovrebbe essere utilizzato perché è l'unica codifica consentita dal nuovo standard IRI (RFC 3987, http://tools.ietf.org/html/rfc3986) che sostituisce lo standard URL precedente. –

+3

Nel caso in cui gli altri sono sorpreso come ero, il testo di @ RemyLebeau commento menziona RFC3987, ma il collegamento è alla specifica più vecchia 3896. L'URL corretto è ovviamente http://tools.ietf.org/html/rfc3987 – tripleee

+0

Sì , mi dispiace per quello.URI è definito da RFC 3986, IRI è definito da RFC 3987. –

0

La prima domanda è quali sono le vostre esigenze? La codifica UTF-8 è un compromesso piuttosto buono tra l'assunzione di testo creato con un editor economico e il supporto per un'ampia varietà di lingue.Per quanto riguarda il browser che identifica la codifica, la risposta (dal server web) dovrebbe indicare al browser la codifica. La maggior parte dei browser tenterà comunque di indovinare, perché in molti casi questo è mancante o sbagliato. Immaginano leggendo una parte del flusso dei risultati per vedere se c'è un personaggio che non rientra nella codifica predefinita. Attualmente tutto il browser (? Non ho controllato questo, ma è abbastanza vicino al vero) usa utf-8 come predefinito.

Così utilizzare utf-8 a meno che non si dispone di un motivo valido per utilizzare uno dei tanti altri schemi di codifica.

9

La regola generale sembra essere che i browser codificano le risposte del modulo in base al tipo di contenuto della pagina da cui è stato servito il modulo. Questa è un'ipotesi che se il server ci invia "text/xml; charset = iso-8859-1", allora si aspettano le risposte nello stesso formato.

Se sei solo immettendo un URL nella barra degli indirizzi, quindi il browser non avere una pagina di base su cui lavorare e quindi ha solo da indovinare. Quindi in questo caso sembra che stia facendo utf-8 tutto il tempo (dal momento che entrambi i tuoi input hanno prodotto valori di tre ottetti).

La triste verità è che per quanto ne so non c'è standard per ciò che set di caratteri i valori in una stringa di query, o anche qualsiasi carattere nella URL, deve essere interpretata come. Almeno nel caso di valori nella stringa di query, non c'è motivo di supporre che siano necessariamente do corrispondenti a caratteri.

È un problema noto che devi dire al tuo server framework quale set di caratteri ti aspetti che la stringa di query sia codificata come --- per esempio, in Tomcat, devi chiamare request.setEncoding() (o qualcosa di simile metodo) prima di si chiama uno dei metodi request.getParameter(). La mancanza di documentazione su questo argomento probabilmente riflette la mancanza di consapevolezza del problema tra molti sviluppatori. (Chiedo regolarmente intervistati Java ciò che la differenza tra un lettore e un InputStream è, e regolarmente ottengo sguardi vuoti)

+5

RFC 3987 (http://tools.ietf.org/html/rfc3986) definisce un standard di codifica - UTF-8 deve essere utilizzato quando la codifica dei caratteri che non sono altrimenti consentito non codificato. –

6

IRI (RFC 3987) è il più recente standard che sostituisce l'URI/URL (RFC 3986 e più vecchio) standard. URI/URL non supportano nativamente Unicode (beh, RFC 3986 aggiunge disposizioni per i futuri protocolli basati su URI/URL per supportarlo, ma non aggiorna i RFC passati). Lo schema "% uXXXX" è un'estensione non standard per consentire Unicode in alcune situazioni, ma non è universalmente implementato da tutti. L'IRI, d'altra parte, supporta pienamente Unicode e richiede che il testo sia codificato come UTF-8 prima di essere codificato in percentuale.

+0

desidero vedere un aggiornamento ai protocolli modo che unicode sono completamente supportati negli URL, non solo tramite percentuale di codifica. – shigazaru

+1

IRIS permette di caratteri Unicode non-codificato, tranne nei pochi casi in cui deve essere codificato caratteri riservati. –

5

IRI non sostituiscono URI, perché solo URI (in modo efficace, ASCII) sono ammesse in alcuni contesti - tra cui HTTP.

Invece, si specifica un IRI e si trasforma in un URI quando si va sul filo.

Problemi correlati