Qual è il modo corretto per codificare in URL i caratteri Unicode?


107

Conosco lo schema% uxxxx non standard ma non mi sembra una scelta saggia poiché lo schema è stato rifiutato dal W3C.

Alcuni esempi interessanti:

Il carattere del cuore. Se lo digito nel mio browser:

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

Quindi copialo e incollalo, vedo questo URL

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

il che fa sembrare che Firefox (o Safari) lo stia facendo.

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

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

Se digito l'URL

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

nel mio browser quindi copia e incolla, ottengo

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

indietro. Che sembra essere il risultato del fare

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

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

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

Poiché questo sembra essere ambiguo:

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

funziona, quindi non so come il browser capisca se decodificarlo con UTF-8 o Latin-1.

Qual è la cosa giusta da fare con i caratteri speciali di cui ho bisogno?


19
Entrambi i tuoi esempi sono codificati come UTF-8. Il primo certamente non latino-1, dato che è lungo tre byte ...
Jakob Borg

2
% E2% 99% A5 è esadecimale per i valori in byte del "seme del cuore nero" in UTF-8 . Quel cuore nero non fa parte del set di caratteri Latin-1 .
Hawkeye Parker

Per vedere in modo affidabile esattamente come e cosa sta codificando un browser (e molte altre informazioni utili), utilizza gli strumenti di sviluppo integrati nella maggior parte dei browser moderni o ottieni un debugger HTTP gratuito come Fiddler .
Hawkeye Parker

Risposte:


65

Vorrei sempre codificare in UTF-8. Dalla pagina di Wikipedia sulla codifica percentuale :

La sintassi URI generica impone che i nuovi schemi URI che forniscono la rappresentazione dei dati dei caratteri in un URI debbano, in effetti, rappresentare i caratteri del set non riservato senza traduzione e dovrebbero convertire tutti gli altri caratteri in byte secondo UTF-8, e quindi codifica in percentuale questi valori. Questo requisito è stato introdotto nel gennaio 2005 con la pubblicazione dell'RFC 3986 . Gli schemi URI introdotti prima di questa data non sono interessati.

Sembra che, poiché in passato esistevano altri modi accettati per eseguire la codifica URL, i browser tentano diversi metodi per decodificare un URI, ma se sei tu a fare la codifica dovresti usare UTF-8.


8
UTF-8 dovrebbe essere utilizzato anche perché è l'unica codifica consentita dal nuovo standard IRI (RFC 3987, tools.ietf.org/html/rfc3986 ) che sta sostituendo il vecchio standard URL.
Remy Lebeau

3
Nel caso in cui altri siano sorpresi come me, il testo nel commento di @ RemyLebeau menziona RFC3987, ma il collegamento è alla vecchia specifica 3896. L'URL corretto è ovviamente tools.ietf.org/html/rfc3987
tripleee

Sì, mi dispiace per questo. L'URI è definito da RFC 3986, IRI è definito da RFC 3987.
Remy Lebeau

10

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", si aspettano risposte nello stesso formato.

Se stai solo inserendo un URL nella barra degli URL, il browser non ha una pagina di base su cui lavorare e quindi deve solo indovinare. Quindi in questo caso sembra che stia facendo utf-8 tutto il tempo (poiché entrambi gli input hanno prodotto valori di forma a tre ottetti).

La triste verità è che AFAIK non esiste uno standard per quale set di caratteri i valori in una stringa di query, o addirittura qualsiasi carattere nell'URL, dovrebbero essere interpretati come. Almeno nel caso di valori nella stringa di query, non c'è motivo di supporre che essi necessariamente fanno corrispondono a caratteri.

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


6
RFC 3987 ( tools.ietf.org/html/rfc3986 ) definisce una codifica standard - UTF-8 deve essere utilizzato quando si codificano caratteri che non sono altrimenti consentiti non codificati.
Remy Lebeau

8

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


Vorrei vedere un aggiornamento ai protocolli in modo che Unicode sia completamente supportato negli URL, non solo tramite la codifica percentuale.
Mathieu J.

1
Gli IRI consentono caratteri Unicode non codificati, tranne nei pochi casi in cui i caratteri riservati devono essere codificati.
Remy Lebeau

6

Gli IRI non sostituiscono gli URI, perché solo gli URI (effettivamente, ASCII) sono consentiti in alcuni contesti, incluso HTTP.

Invece, si specifica un IRI e viene trasformato in un URI quando si esce sul cavo.


0

La prima domanda è quali sono le tue esigenze? La codifica UTF-8 è un buon compromesso tra il prendere il 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 comunicare al browser la codifica. Tuttavia la maggior parte dei browser tenterà di indovinare, perché in molti casi questo è mancante o sbagliato. Immaginano leggendo una parte del flusso di risultati per vedere se c'è un carattere che non si adatta alla codifica predefinita. Attualmente tutti i browser (? Non l'ho controllato, ma è abbastanza vicino al vero) usano utf-8 come predefinito.

Quindi usa utf-8 a meno che tu non abbia un motivo valido per usare uno dei tanti altri schemi di codifica.

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.