IDN Ferramentas conscientes para codificar/decodificar IRI legível por humanos para/para Uri válido [fechado
-
26-09-2019 - |
Pergunta
Vamos supor que um usuário insira o endereço de algum recurso e precisamos traduzi -lo para:
<a href="valid URI here">human readable form</a>
Especificação HTML4 refere -se a RFC 3986 O que permite apenas caracteres alfanuméricos ASCII e Dash na parte do host e todo o caractere não-ASCII em outras partes deve ser codificado porcentagem. É isso que eu quero colocar no atributo href para fazer o Link funcionar corretamente em todos os navegadores. Idn deve ser codificado com Punycode.
Draft html5 refere -se a RFC 3987 que também permite caracteres unicode codificados por percentual na parte do host e um grande subconjunto de unicode no host e em outras partes sem codificá-los. O usuário pode inserir o endereço em qualquer um desses formulários. Para fornecer uma forma legível humana, preciso decodificar todos os caracteres imprimíveis. Observe que algumas partes do endereço podem não corresponder às sequências UTF-8 válidas, geralmente quando o site do destino usa outra codificação de caracteres.
Um exemplo do que eu gostaria de obter:
<a href="http://xn--80aswg.xn--p1ai/%D0%BF%D1%83%D1%82%D1%8C?%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81">
http://сайт.рф/путь?запрос</a>
Existem ferramentas para resolver essas tarefas? Estou especialmente interessado em bibliotecas para Python e JavaScript.
Atualizar: Eu sei que existe uma maneira de fazer porcentagem e punycode (sem normalização adequada, mas eu posso viver com ela) codificação/decodificação em python e javascript. Toda a tarefa precisa de muito mais trabalho e existem algumas armadilhas (alguns caracteres devem ser sempre codificados ou nunca codificados, dependendo do contexto). Gostaria de saber se estão prontos para usar bibliotecas para o todo Problema, já que parece ser bastante comum e os navegadores modernos já fazem essas conversões (tente digitar http://%D1%81%D0%B0%D0%B9%D1%82.%D1%80%D1%84/
no Google Chrome e será substituído por http://сайт.рф/
, mas use Host: xn--80aswg.xn--p1ai
na solicitação HTTP).
Atualização2: Vinay Sajip apontou que o Werkzeug tem IRI_TO_URI e URI_TO_IRI FUNCIÇÕES que lidam com a maioria dos casos corretamente. Encontrei apenas 2 casos em que falha até agora: host codificado por cento (muito fácil de corrigir) e sequências UTF-8 inválidas (é um pouco complicado fazer bem, mas não deve ser um problema).
Ainda estou procurando biblioteca em JavaScript. Não é difícil escrever, mas prefiro evitar inventar a roda.
Solução
Se eu entendi corretamente, você pode usar as baterias incluídas no Python:
# -*- coding: utf-8 -*-
import urllib
import urlparse
URL1 = u'http://сайт.рф/путь?запрос'
URL2 = 'http://%D1%81%D0%B0%D0%B9%D1%82.%D1%80%D1%84/'
def to_idn(url):
parts = list(urlparse.urlparse(url))
parts[1] = parts[1].encode('idna')
parts[2:] = [urllib.quote(s.encode('utf-8')) for s in parts[2:]]
return urlparse.urlunparse(parts)
def from_idn(url):
return urllib.unquote(url)
print to_idn(URL1)
print from_idn(URL2)
print to_idn(from_idn(URL2).decode('utf-8'))
que imprime
http://xn--80aswg.xn--p1ai/%D0%BF%D1%83%D1%82%D1%8C?%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81
http://сайт.рф/
http://xn--80aswg.xn--p1ai/
que se parece com o que você quer. Não tenho certeza de quais casos especiais você quer dizer - talvez você possa dar alguns exemplos das armadilhas às quais está se referindo?
Atualizar: Acabei de me lembrar, Werkzeug tem iri_to_uri
e uri_to_iri
Funções nas versões 0.6 e posterior (os links são para a parte relevante dos documentos).
Atualização adicional: Desculpe, eu não tinha notado que você está procurando uma implementação de JavaScript, bem como um Python. Uma implementação de JavaScript de domínio público existente de punycode é aqui. Eu não posso garantir isso, no entanto. E é claro que você pode usar o javascript embutido encodeURI
/decodeURI
APIs.