Ruby - 国际化域名

时间:2010-07-12 09:12:32

标签: ruby

我需要在我正在撰写的应用中支持国际化域名。更具体地说,在将域名传递给外部API之前,我需要对域名进行ACE编码。

最好的方法是使用libidn。但是,我在开发机器上安装它时遇到问题(Windows 7,ruby 1.8.6),因为它抱怨没有找到GNU IDN库(我已安装它,并提供了完整路径)。

所以基本上我在考虑两件事:

  1. 在网上搜索预建的win32 libidn gem(到目前为止毫无结果)

  2. 找到另一个(希望是纯粹的)ruby库,它可以做同样的事情(我在这里问这个问题并不是很明显)

  3. 你们有没有人让libidn在Windows下工作?或者您是否使用过其他能够对域名进行编码的库/代码片段?

1 个答案:

答案 0 :(得分:3)

感谢this snippet,我终于找到了一个不需要libidn的解决方案。它基于punicode4r以及unicode gem(可以找到预构建的二进制文件here)或ActiveSupport构建。我将使用ActiveSupport,因为我仍然使用Rails,但作为参考,我包括两种方法。

使用 unicode gem:

require 'unicode'
require 'punycode' #This is not a gem, but a standalone file.

   def idn_encode(domain)
    parts = domain.split(".").map do |label|
        encoded = Punycode.encode(Unicode::normalize_KC(Unicode::downcase(label)))
        if encoded =~ /-$/ #Pure ASCII
            encoded.chop!
        else #Contains non-ASCII characters
            "xn--" + encoded
        end
    end
    parts.join(".")
end

使用 ActiveSupport

require "punycode"
require "active_support"
$KCODE = "UTF-8" #Have to set this to enable mb_chars

def idn_encode(domain)
    parts = domain.split(".").map do |label|
        encoded = Punycode.encode(label.mb_chars.downcase.normalize(:kc))
        if encoded =~ /-$/ #Pure ASCII
            encoded.chop! #Remove trailing '-'
        else #Contains non-ASCII characters
            "xn--" + encoded
        end
    end
    parts.join(".")
end

由于this StackOverflow问题,找到了ActiveSupport解决方案。