2009-05-26 10 views
96

Conozco el esquema% uxxxx no estándar pero eso no parece una buena elección ya que el esquema ha sido rechazado por el W3C.¿Cuál es la forma correcta de codificación URL de caracteres Unicode?

Algunos ejemplos interesantes:

El carácter de corazón. si escribo esto en mi navegador:

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

luego copiar y pegar, veo este URL

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

lo que hace que parezca que Firefox (o Safari) está haciendo esto.

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

que tiene sentido, a excepción de las cosas que no se pueden codificar en Latin-1, como el carácter de punto triple.

Si escribo la URL

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

en mi navegador y luego copiar y pegar, me sale

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

espalda. Que parece ser el resultado de hacer

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

cual tiene sentido ya que ... no puede ser codificado con Latin-1.

Pero no está claro para mí cómo sabe el navegador si decodificar con UTF-8 o Latin-1.

Dado que este parece ser ambigua:

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

obras, por lo que no saben cómo calcula el navegador a cabo ya sea para decodificar que con UTF-8 o Latin-1.

¿Qué hay que hacer con los personajes especiales con los que tengo que lidiar?

+16

Ambos ejemplos están codificados como UTF-8. El primero ciertamente no es Latin-1, dado que tiene tres bytes de longitud ... –

+1

% E2% 99% A5 es hexadecimal para los valores de byte de [el "traje de corazón negro" en UTF-8] (http: // www. ltg.ed.ac.uk/~richard/utf-8.cgi?input=E2+99+A5&mode=bytes). Ese corazón negro no es parte del conjunto de caracteres [Latin-1] (http://en.wikipedia.org/wiki/ISO/IEC_8859-1). –

+0

Para ver exactamente cómo y qué navegador está codificando (y mucha otra información útil), use las herramientas de desarrollador integradas en los navegadores más modernos o obtenga un depurador HTTP gratuito como [Fiddler] (http: //www.telerik .com/fiddler). –

Respuesta

54

Siempre codificaré en UTF-8. Desde el Wikipedia page on percent encoding:

Los genéricos mandatos de sintaxis URI que los nuevos esquemas URI que proporcionan para la representación de datos de caracteres en un URI debe, en efecto, representar caracteres del juego sin reservas y sin traducción, y deben convertir todos los demás caracteres a bytes de acuerdo con UTF-8, y luego porcentaje de codificar esos valores. Este requisito se introdujo en enero de 2005 con la publicación RFC 3986. Los esquemas de URI introducidos antes de esta fecha no se ven afectados.

Parece que ya había otras formas aceptadas de hacer la codificación URL en el pasado, los navegadores intentan varios métodos de decodificación de una URI, pero si usted es el que hace la codificación que se debe utilizar UTF-8.

+8

UTF-8 también se debe utilizar porque es la única codificación permitida por el nuevo estándar IRI (RFC 3987, http://tools.ietf.org/html/rfc3986) que está reemplazando el estándar de URL anterior. –

+3

En caso de que otros estén tan sorprendidos como yo, el texto en el comentario de @RemyLebeau menciona RFC3987, pero el enlace es a la especificación anterior 3896. La URL correcta es obviamente http://tools.ietf.org/html/rfc3987 – tripleee

+0

Sí , Lo siento por eso.URI está definido por RFC 3986, IRI está definido por RFC 3987. –

0

La primera pregunta es ¿cuáles son sus necesidades? La codificación UTF-8 es un buen compromiso entre tomar texto creado con un editor barato y soporte para una amplia variedad de idiomas.Con respecto al navegador que identifica la codificación, la respuesta (del servidor web) debe indicarle al navegador la codificación. Sin embargo, la mayoría de los navegadores intentarán adivinar, porque esto falta o está mal en muchos casos. Adivinan al leer una cierta cantidad del flujo de resultados para ver si hay un personaje que no cabe en la codificación predeterminada. Actualmente, todos los navegadores (? No lo he comprobado, pero está muy cerca de la verdad) usan utf-8 como valor predeterminado.

Así que use utf-8 a menos que tenga un motivo convincente para utilizar uno de los muchos otros esquemas de codificación.

9

La regla general parece ser que los navegadores codifican las respuestas de formulario de acuerdo con el tipo de contenido de la página desde la que se envió el formulario. Se supone que si el servidor nos envía "text/xml; charset = iso-8859-1", esperan que las respuestas vuelvan a tener el mismo formato.

Si solo está ingresando una URL en la barra de URL, entonces el navegador no tiene una página base para trabajar y por lo tanto solo tiene que adivinar. Entonces, en este caso, parece estar haciendo utf-8 todo el tiempo (ya que ambas entradas produjeron valores de forma de tres octetos).

La triste verdad es que AFAIK no hay un estándar para qué carácter establecer los valores en una cadena de consulta, o de hecho, cualquier carácter en la URL, debe interpretarse como. Al menos en el caso de valores en la cadena de consulta, no hay ninguna razón para suponer que necesariamente do corresponden a caracteres.

Es un problema conocido que tiene que indicarle a su estructura de servidor qué conjunto de caracteres espera que la cadena de consulta se codifique como --- por ejemplo, en Tomcat, debe llamar a request.setEncoding() (o similar método) antes de llama a cualquiera de los métodos request.getParameter(). La escasez de documentación sobre este tema probablemente refleja la falta de conocimiento del problema entre muchos desarrolladores. (Me pregunto regularmente entrevistados Java cuál es la diferencia entre un lector y un InputStream es, y recibe regularmente miradas en blanco)

+5

RFC 3987 (http://tools.ietf.org/html/rfc3986) define una codificación estándar - UTF-8 debe usarse cuando se codifican caracteres que no son de otra manera permitido sin codificar –

6

IRI (RFC 3987) es el último estándar que sustituye a la URI/URL (RFC 3986 y mayores) estándares. URI/URL no admite de forma nativa Unicode (bueno, RFC 3986 agrega disposiciones para futuros protocolos basados ​​en URI/URL para admitirlo, pero no actualiza las RFC pasadas). El esquema "% uXXXX" es una extensión no estándar para permitir Unicode en algunas situaciones, pero no es universalmente implementado por todos. IRI, por otro lado, es completamente compatible con Unicode, y requiere que el texto se codifique como UTF-8 antes de que se codifique porcentualmente.

+0

Deseo ver una actualización de los protocolos para que Unicode sea totalmente compatible con las URL, no solo a través de la codificación porcentual. – shigazaru

+1

IRI permite caracteres Unicode no codificados, excepto en los pocos casos donde los caracteres reservados deben codificarse. –

5

Los IRI no reemplazan los URI, porque solo los URI (efectivamente, ASCII) son permisibles en algunos contextos, incluido HTTP.

En su lugar, especifica un IRI y se transforma en un URI al salir en el cable.

Cuestiones relacionadas