2012-01-03 1 views
3

Не знаю, почему я получаю следующее сообщение об ошибке, когда URI отлично работает в браузере:Руби/Rails - Bad URI

http://oracleofbacon.org/cgi-bin/xml?a=Kevin Bacon&b=Tom Cruise&u=1&p=google-apps 

Это мой код:

def kb(to) 

    uri = "http://oracleofbacon.org/cgi-bin/xml?a=Kevin Bacon&b=#{to.strip}&u=1&p=google-apps" 
    doc = Nokogiri::XML(open(uri)) # throws error on this line 

    return parse(doc) 
end 

Я получаю следующее сообщение об ошибке:

in `split': bad URI(is not URI?): http://oracleofbacon.org/cgi-bin/xml?a=Kevin Bacon&b=Tom Cruise&u=1&p=google-apps (URI::InvalidURIError)` 

я выполнить метод следующим образом:

kb("Tom Cruise") 
+0

Покажите нам некоторый код –

ответ

20

Это потому, что браузер является патологически дружественным, как щенок, и пойдет на большие длины, чтобы отобразить страницу или разрешить URL-адрес. Приложение не сделает этого, потому что вы должны сказать ему, как быть дружелюбным.

Ваш адрес недействителен, так как он имеет встроенные пространства. Заменить пробелы с %20:

irb -f 
irb(main):001:0> require 'open-uri' 
=> true 
irb(main):002:0> open('http://oracleofbacon.org/cgi-bin/xml?a=Kevin%20Bacon&b=Tom%20Cruise&u=1&p=google-apps').read 
=> "<?xml version=\"1.0\" standalone=\"no\"?>\n<link><actor>Tom Cruise</actor><movie>A Few Good Men (1992)</movie><actor>Kevin Bacon</actor></link>" 

Экранирование символов, которым нужно экранировать легко:

irb -f 
irb(main):001:0> require 'uri' 
=> true 
irb(main):002:0> URI.escape('http://oracleofbacon.org/cgi-bin/xml?a=Kevin Bacon&b=Tom Cruise&u=1&p=google-apps') 
=> "http://oracleofbacon.org/cgi-bin/xml?a=Kevin%20Bacon&b=Tom%20Cruise&u=1&p=google-apps" 
+0

работал лакомство, спасибо. Я сделал следующее, но я уверен, что должен быть более чистый способ замены пространства% 20: '# {to.strip.gsub (" ","% 20 ")}' – fuzz

+0

@Fulvio 'require 'cgi «; CGI :: escape («Stop!» Сказал Фред ») # =>«% 27Stop% 21% 27 + said + Fred »' ([doc] (http://ruby-doc.org/stdlib-1.9.3) /libdoc/cgi/rdoc/CGI.html#method-c-escape)). (или вспомогательный метод «h» в рельсах). – steenslag

+0

@Fulvio, я добавил код, показывающий, как обращаться с экранированием строки. Использование 'gsub' в порядке, если вы знаете, что нужно заменить только один символ. Помимо этого вы должны воспользоваться заранее изобретенным колесом и перейти с [URI] (http://rubydoc.info/stdlib/uri/frames) или [Addressable] (http://rubydoc.info/gems/addressable/frames), который является очень полнофункциональным. –