【问题标题】:IDN aware tools to encode/decode human readable IRI to/from valid URI [closed]IDN 感知工具可将人类可读的 IRI 编码/解码到有效 URI [关闭]
【发布时间】:2010-05-14 09:19:30
【问题描述】:

假设用户输入了某个资源的地址,我们需要将其翻译成:

<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(没有适当的规范化,但我可以接受)编码/解码。整个任务需要更多的工作,并且存在一些陷阱(某些字符应始终编码或从不编码,具体取决于上下文)。我想知道是否有准备好使用库来解决 whole 问题,因为它似乎很常见,而且现代浏览器已经进行了此类转换(尝试在 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 函数。到目前为止,我只发现了两种失败的情况:百分比编码的主机(很容易修复)和无效的 utf-8 序列(做得好有点棘手,但应该不是问题)。

我仍在寻找 JavaScript 中的库。写起来不难,但我宁愿避免发明轮子。

【问题讨论】:

  • 感谢您的链接。问题不仅仅是 Punycode 编码实现(很简单),而是一个更大的问题。
  • 那么你可能应该澄清一下,因为我仍然没有得到你的要求。
  • 我在对 Javascript 实现的回答中添加了一个链接,它也许可以适应您的需求。我想说,它是公共领域,但需要单元测试。

标签: javascript python html idn iri


【解决方案1】:

如果我理解正确,那么您可以使用 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_uriuri_to_iri 函数(链接指向文档的相关部分)。

进一步更新:抱歉,我没有注意到您正在寻找一个 JavaScript 实现以及一个 Python 实现。 punycode 的现有公共领域 Javascript 实现是 here。不过,我不能保证。当然,您也可以使用内置的 JavaScript encodeURI/decodeURI API。

【讨论】:

  • 您的函数仅适用于本示例。 Werkzeug 函数适用于大多数情况,其余情况可以轻松修复,谢谢!
  • 您的编码行有 -' 而不是 --。为了避免这种混乱,你可以写 #coding: utf-8
猜你喜欢
  • 2012-02-09
  • 1970-01-01
  • 2010-11-15
  • 2018-04-16
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
相关资源
最近更新 更多