使用ruby显示来自规范化URI的IDN(使用可寻址Gem)

使用ruby显示来自规范化URI的IDN(使用可寻址Gem),ruby,uri,ruby-2.0,idn,addressable-gem,Ruby,Uri,Ruby 2.0,Idn,Addressable Gem,在我的Ruby应用程序中,我需要处理来自用户输入的URI(实际上是IRIs) 我使用可寻址来规范化这些,并且只存储规范化的表单: normalized = Addressable::URI.parse(str).normalize normalized.to_s #=> http://xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g/%E0%A4%AE%E0%A5%81%E0%A4%96%E0%A5%8D%E0%A4%AF_%E0%A4%AA%E0%A5%83%E0%A

在我的Ruby应用程序中,我需要处理来自用户输入的URI(实际上是IRIs)

我使用可寻址来规范化这些,并且只存储规范化的表单:

normalized = Addressable::URI.parse(str).normalize
normalized.to_s
#=> http://xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g/%E0%A4%AE%E0%A5%81%E0%A4%96%E0%A5%8D%E0%A4%AF_%E0%A4%AA%E0%A5%83%E0%A4%B7%E0%A5%8D%E0%A4%A0
这很好用,但显然不适合向最终用户显示

为此,我想将此URI转换回其原始形式(非punycode,非百分比编码路径)

可寻址具有
显示uri
,但它仅转换主机:

nicer = normalized.display_uri.to_s
#=> http://उदाहरण.परीक्षा/%E0%A4%AE%E0%A5%81%E0%A4%96%E0%A5%8D%E0%A4%AF_%E0%A4%AA%E0%A5%83%E0%A4%B7%E0%A5%8D%E0%A4%A0
这看起来很有效:

display_s = Addressable::URI.parse(str).display_uri.to_s
pretty = Addressable::URI.unencode(display_s.force_encoding("ASCII-8BIT"))
但是,该代码看起来是错误的(我不需要使用
force_编码
),我对它的正确性没有信心

  • 将整个URI转换为可供最终用户使用的内容(http://उदाहरण.परीक्षा/मुख्य_पृष्ठ"

  • 存储URI规范化是一个好主意,还是会产生我可能不知道的后果

代码:

太长,读不下去了 如何将其转换为:

"http://xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g/" +
"%E0%A4%AE%E0%A5%81%E0%A4%96%E0%A5%8D%E0%A4" +
"%AF_%E0%A4%AA%E0%A5%83%E0%A4%B7%E0%A5%8D%E0%A4%A0"
为此:

"http://उदाहरण.परीक्षा/मुख्य_पृष्ठ"

您不需要任何强制(重新)编码来恢复原始URI。只需:

normalised_s = "http://xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g/%E0%A4%AE%E0%A5%81%E0%A4%96%E0%A5%8D%E0%A4%AF_%E0%A4%AA%E0%A5%83%E0%A4%B7%E0%A5%8D%E0%A4%A0"        
Addressable::URI.unencode(Addressable::URI.parse(normalised_s).display_uri)

=> "http://उदाहरण.परीक्षा/मुख्य_पृष्ठ"

重复Bob在评论中所说的,规范化绝对是保证存储唯一性的一个好方法。

首先,使用可寻址的+1。如果数据库正常接受规范化的URI,我看不到存储它有什么好处。如果规范化,它会更长,不清楚它是什么,搜索会更困难。n一致性和重复检测的规范化。一开始似乎更简单。现在我不太确定。重复检测可以由数据库自动处理,使用该字段索引上的
唯一
设置。您的代码不应该尝试跟踪它,相反,如果DBM因找到重复的密钥“类型错误。您可能希望规范化以解析具有多个代码点的字符,这些代码点指向同一个字符,尽管这种差异会欺骗索引。或者,如果最终将URL更改为不同的解析方式,则可能不会;这就是小代码的优点。这是一个艰难的决定。好吧,如果一切都规范化了,那么,也只有到那时,数据库的唯一性才会有任何好处。因此,如果重复检测是一种理想的行为,那么在将字段存储到数据库之前进行规范化是100%正确的选择
normalised_s = "http://xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g/%E0%A4%AE%E0%A5%81%E0%A4%96%E0%A5%8D%E0%A4%AF_%E0%A4%AA%E0%A5%83%E0%A4%B7%E0%A5%8D%E0%A4%A0"        
Addressable::URI.unencode(Addressable::URI.parse(normalised_s).display_uri)

=> "http://उदाहरण.परीक्षा/मुख्य_पृष्ठ"