是否有解决方法在Ruby中打开包含下划线的URL?

Art*_*rty 32 ruby open-uri

我正在使用open-uri来打开URL.

resp = open("http://sub_domain.domain.com")
Run Code Online (Sandbox Code Playgroud)

如果它包含下划线,我会收到一个错误:

URI::InvalidURIError: the scheme http does not accept registry part: sub_domain.domain.com (or bad hostname?)

我理解这是因为根据RFC URL只能包含字母和数字.有没有解决方法?

ste*_*tef 19

这看起来像URI中的错误,uri-open,HTTParty和许多其他宝石都使用URI.parse.

这是一个解决方法:

require 'net/http'
require 'open-uri'

def hopen(url)
  begin
    open(url)
  rescue URI::InvalidURIError
    host = url.match(".+\:\/\/([^\/]+)")[1]
    path = url.partition(host)[2] || "/"
    Net::HTTP.get host, path
  end
end

resp = hopen("http://dear_raed.blogspot.com/2009_01_01_archive.html")
Run Code Online (Sandbox Code Playgroud)


pgu*_*rio 17

URI 对网址的外观有一个老式的想法.

最近我addressable用来解决这个问题:

require 'open-uri'
require 'addressable/uri'

class URI::Parser
  def split url
    a = Addressable::URI::parse url
    [a.scheme, a.userinfo, a.host, a.port, nil, a.path, nil, a.query, a.fragment]
  end
end

resp = open("http://sub_domain.domain.com") # Yay!
Run Code Online (Sandbox Code Playgroud)

别忘了 gem install addressable


clu*_*que 14

我的rails应用程序中的这个初始化程序似乎至少使URI.parse工作:

# config/initializers/uri_underscore.rb
class URI::Generic
  def initialize_with_registry_check(scheme,
                 userinfo, host, port, registry,
                 path, opaque,
                 query,
                 fragment,
                 parser = DEFAULT_PARSER,
                 arg_check = false)
    if %w(http https).include?(scheme) && host.nil? && registry =~ /_/
      initialize_without_registry_check(scheme, userinfo, registry, port, nil, path, opaque, query, fragment, parser, arg_check)
    else
      initialize_without_registry_check(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser, arg_check)
    end
  end
  alias_method_chain :initialize, :registry_check
end
Run Code Online (Sandbox Code Playgroud)


Lar*_*ala 6

这是一个补丁,可以在不使用外部 gem 或覆盖 URI.parse 的部分的情况下解决各种情况(rest-client、open-uri 等)的问题:

module URI
  DEFAULT_PARSER = Parser.new(:HOSTNAME => "(?:(?:[a-zA-Z\\d](?:[-\\_a-zA-Z\\d]*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:[-\\_a-zA-Z\\d]*[a-zA-Z\\d])?)\\.?")
end
Run Code Online (Sandbox Code Playgroud)

来源:lib/uri/rfc2396_parser.rb#L86

Ruby-core 有一个未解决的问题:https : //bugs.ruby-lang.org/issues/8241