如何使用Ruby on Rails发出HTTP请求?

use*_*052 234 ruby http request ruby-on-rails-3

我想从其他网站获取信息.因此(也许)我应该向该网站发出请求(在我的情况下是HTTP GET请求)并接收响应.

我如何在Ruby on Rails中实现这一点?

如果可能的话,在我的控制器中使用它是否正确?

Joã*_*lva 322

你可以使用Ruby的Net::HTTP类:

require 'net/http'

url = URI.parse('http://www.example.com/index.html')
req = Net::HTTP::Get.new(url.to_s)
res = Net::HTTP.start(url.host, url.port) {|http|
  http.request(req)
}
puts res.body
Run Code Online (Sandbox Code Playgroud)

  • 这意味着请求 (15认同)

ste*_*tef 106

Net :: HTTP内置于Ruby中,但让我们面对它,通常更容易使用其繁琐的20世纪80年代风格并尝试更高级别的替代方案:

  • 我想提醒您不要这样做,因为您将为rails应用添加更多依赖项.更多的依赖性意味着更多的内存消耗,也可能是更大的攻击面.使用`Net :: HTTP`很麻烦,但权衡不值得. (7认同)
  • 或者Rails附带的ActiveResource! (4认同)
  • 这应该是公认的答案.为什么要编程才能安装大量宝石? (3认同)
  • @JasonYeo完全不同意。引入依赖项意味着您无需重新发明轮子,而您将从他人已经完成的艰苦工作中受益。如果有一颗让您的生活更轻松的宝石,通常没有充分的理由不使用它。 (3认同)
  • @JasonYeo leftpad 传奇之所以发生,是因为 NPM 的存储库运行不佳,并让作者删除了他的所有包。正确管理的软件包存储库不会这样做(无论如何,它是 OSS,因此如果您愿意,您可以轻松镜像)。也就是说,leftpad 传奇并不是反对引入一般依赖项的论据,而是反对对存储库管理不善。我确实同意你的另一点,即对它所提供的价值而言,超出你需要的巨大依赖可能会造成过度杀伤力。 (2认同)

use*_*031 90

OpenURI是最好的; 它很简单

require 'open-uri'
response = open('http://example.com').read
Run Code Online (Sandbox Code Playgroud)

  • 警告,"open-uri"不会遵循重定向,这一点很重要. (9认同)
  • @yagooar很棒,可以防止像`file:/// etc/passwd`这样的恶意重定向 (3认同)
  • 请注意,它不会关闭连接。使用 /sf/answers/295208861/ (2认同)

And*_*ich 77

require 'net/http'
result = Net::HTTP.get(URI.parse('http://www.example.com/about.html'))
# or
result = Net::HTTP.get(URI.parse('http://www.example.com'), '/about.html')
Run Code Online (Sandbox Code Playgroud)


Mar*_*mas 13

我更喜欢httpclient而不是Net :: HTTP.

client = HTTPClient.new
puts client.get_content('http://www.example.com/index.html')
Run Code Online (Sandbox Code Playgroud)

如果您正在创建一个服务客户端的类,那么HTTParty是一个不错的选择.这是一个方便的mixin,为您提供90%的需求.了解示例中 Google和Twitter客户端的简短程度.

并回答你的第二个问题:不,我不会将此功能放在控制器中 - 如果可能的话,我会使用模型来封装细节(可能使用HTTParty)并简单地从控制器中调用它.


the*_*Man 8

我最喜欢的两种获取URL内容的方法是OpenURITyphoeus.

OpenURI因为它无处不在,而Typhoeus因为它非常灵活和强大.


mac*_*qcq 8

如果您在代理后面进行REST api调用,则以下代码可用:

require "uri"
require 'net/http'

proxy_host = '<proxy addr>'
proxy_port = '<proxy_port>'
proxy_user = '<username>'
proxy_pass = '<password>'

uri = URI.parse("https://saucelabs.com:80/rest/v1/users/<username>")
proxy = Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass)

req = Net::HTTP::Get.new(uri.path)
req.basic_auth(<sauce_username>,<sauce_password>)

result = proxy.start(uri.host,uri.port) do |http|
http.request(req)
end

puts result.body
Run Code Online (Sandbox Code Playgroud)