IDN Ferramentas conscientes para codificar/decodificar IRI legível por humanos para/para Uri válido [fechado

StackOverflow https://stackoverflow.com/questions/2833013

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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top