假设用户输入某些资源的地址,我们需要将其翻译为:
<a href="valid URI here">human readable form</a>
HTML4规范是指RFC 3986,它只允许ASCII字母数字字符和主机部分中的破折号,其他部分中的所有非ASCII字符都应进行百分比编码。这就是我想要放在href属性中以使链接在所有浏览器中正常工作。 IDN应使用Punycode进行编码。
HTML5草案引用RFC 3987,它还允许主机部分中的百分比编码的unicode字符和主机和其他部分中的大部分unicode,而不对其进行编码。用户可以以任何这些形式输入地址。为了提供它的可读形式,我需要解码所有可打印的字符。请注意,地址的某些部分可能与有效的UTF-8序列不对应,通常是在目标站点使用其他字符编码时。
我想得到的一个例子:
<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>
是否有任何工具可以解决这些问题?我对Python和JavaScript的库特别感兴趣。
更新:我知道有一种方法可以在Python和JavaScript中进行百分比和Punycode(没有适当的规范化,但我可以忍受它)编码/解码。整个任务需要更多的工作,并且存在一些缺陷(一些字符应该总是编码或从不编码,具体取决于上下文)。我想知道是否有准备使用库来解决整个问题,因为它似乎很常见,现代浏览器已经进行了这样的转换(尝试在Google Chrome中输入http://%D1%81%D0%B0%D0%B9%D1%82.%D1%80%D1%84/
,它会是替换为http://сайт.рф/
,但在HTTP请求中使用Host: xn--80aswg.xn--p1ai
。
Update2 :Vinay Sajip指出Werkzeug有iri_to_uri和uri_to_iri函数可以正确处理大多数情况。到目前为止,我只发现了2个失败的情况:百分比编码的主机(非常容易修复)和无效的utf-8序列(做得好有点棘手,但不应该有问题)。
我仍然在寻找JavaScript中的库。写起来并不难,但我宁愿避免发明轮子。
答案 0 :(得分:2)
如果我理解正确,那么你可以使用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'))
打印
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/
看起来像你想要的。我不确定你的意思是什么特殊情况 - 也许你可以举出一些你所指的陷阱的例子?
更新:我记得,Werkzeug在版本0.6及更高版本中有iri_to_uri
和uri_to_iri
个函数(链接到文档的相关部分)。
进一步更新:抱歉,我没有注意到您正在寻找JavaScript实现以及Python实现。 punycode的现有公共域Javascript实现是here。不过,我无法保证。当然,您可以使用内置的JavaScript encodeURI
/ decodeURI
API。