it-swarm.dev

Qual é a maneira correta de codificar URLs em caracteres Unicode?

Conheço o esquema% uxxxx não padrão, mas isso não parece uma escolha sábia, pois o esquema foi rejeitado pelo W3C.

Alguns exemplos interessantes:

O caráter do coração. Se eu digitar isso no meu navegador:

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

Então copie e cole, eu vejo esse URL

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

o que faz parecer que o Firefox (ou Safari) está fazendo isso.

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

o que faz sentido, exceto por coisas que não podem ser codificadas no Latin-1, como o caractere de ponto triplo.

Se eu digitar o URL

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

no meu navegador, em seguida, copiar e colar, recebo

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

de volta. Qual parece ser o resultado de fazer

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

o que faz sentido desde ... não pode ser codificado com o Latin-1.

Mas então não está claro para mim como o navegador sabe se decodificar com UTF-8 ou Latin-1.

Como isso parece ser ambíguo:

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

funciona, então eu não sei como o navegador descobre se decodificar isso com UTF-8 ou Latin-1.

Qual é a coisa certa a fazer com os personagens especiais com os quais preciso lidar?

105
Josh Gibson

Eu sempre codifico em UTF-8. Do página da Wikipedia na codificação percentual :

A sintaxe genérica do URI determina que novos esquemas de URI que fornecem a representação de dados de caractere em um URI devem, na verdade, representar caracteres do conjunto não reservado sem conversão e converter todos os outros caracteres em bytes de acordo com UTF-8. codificar por cento esses valores. Este requisito foi introduzido em janeiro de 2005 com a publicação de RFC 3986 . Os esquemas de URI introduzidos antes desta data não são afetados.

Parece que, como havia outras formas aceitas de fazer a codificação de URL no passado, os navegadores tentam vários métodos de decodificação de um URI, mas se você é quem está fazendo a codificação, use UTF-8.

61
John Biesnecker

A regra geral parece ser que os navegadores codificam as respostas do formulário de acordo com o tipo de conteúdo da página em que o formulário foi exibido. Isso é um palpite de que, se o servidor nos enviar "text/xml; charset = iso-8859-1", eles esperam respostas no mesmo formato.

Se você acabou de inserir um URL na barra de URL, o navegador não tem uma página de base para trabalhar e, portanto, só precisa adivinhar. Então, neste caso, parece estar fazendo o utf-8 o tempo todo (já que ambas as entradas produziram valores de formulário de três octetos).

A triste verdade é que o AFAIK não possui um padrão para qual conjunto de caracteres os valores em uma string de consulta, ou mesmo qualquer caractere na URL, deve ser interpretado como. Pelo menos no caso de valores na string de consulta, não há razão para supor que eles necessariamente do correspondam a caracteres.

É um problema conhecido que você precisa informar à estrutura do servidor qual conjunto de caracteres você espera que a string de consulta seja codificada como --- por exemplo, no Tomcat, você deve chamar request.setEncoding () (ou algum método semelhante) - antes você chama qualquer um dos métodos request.getParameter (). A escassez de documentação sobre este assunto provavelmente reflete a falta de consciência do problema entre muitos desenvolvedores. (Eu pergunto aos entrevistados Java qual é a diferença entre um Reader e um InputStream e, regularmente, recebo uma aparência vazia)

9
araqnid

IRI ( RFC 3987 ) é o padrão mais recente que substitui os URI/URL ( RFC 3986 e mais antigos). URI/URL não oferece suporte nativo a Unicode (bem, RFC 3986 adiciona provisões para futuros protocolos baseados em URI/URL para dar suporte a ele, mas não atualiza RFCs anteriores). O esquema "% uXXXX" é uma extensão não padrão para permitir Unicode em algumas situações, mas não é universalmente implementada por todos. O IRI, por outro lado, suporta totalmente Unicode e requer que o texto seja codificado como UTF-8 antes de ser codificado por porcentagem.

7
Remy Lebeau

As IRIs não substituem URIs, porque somente URIs (efetivamente, ASCII) são permitidas em alguns contextos - incluindo HTTP.

Em vez disso, você especifica um IRI e ele é transformado em um URI ao sair no fio.

6
Mark Nottingham

A primeira pergunta é quais são suas necessidades? A codificação UTF-8 é um bom compromisso entre a obtenção de texto criado com um editor barato e o suporte a uma ampla variedade de idiomas. No que diz respeito ao navegador que identifica a codificação, a resposta (do servidor da web) deve informar ao navegador a codificação. Ainda assim, a maioria dos navegadores tentará adivinhar, porque isso está ausente ou errado em muitos casos. Eles adivinham lendo alguma quantidade do fluxo de resultados para ver se há um caractere que não se encaixa na codificação padrão. Atualmente todo o navegador (eu não verifiquei isso, mas é bem parecido com true) use utf-8 como padrão.

Portanto, use utf-8, a menos que você tenha um motivo convincente para usar um dos muitos outros esquemas de codificação.

0
Pat O