Jak złożyć żądanie HTTP za pomocą Ruby on Rails?


235

Chciałbym pobrać informacje z innej strony internetowej. Dlatego (być może) powinienem wysłać żądanie do tej witryny (w moim przypadku żądanie HTTP GET) i otrzymać odpowiedź.

Jak mogę to zrobić w Ruby on Rails?

Jeśli to możliwe, czy jest to poprawne podejście w moich kontrolerach?

Odpowiedzi:


329

Możesz użyć Net::HTTPklasy Ruby :

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

1
co znaczy tutaj „req”?
sixty4bit

18
oznacza prośbę
Arthur Collé

1
Wygląda na to, że może to być żądanie blokujące, prawda?
Scott Eisenberg,

gdzie umieścić klucz API?
user1735921,

1
Dodam tylko, że www. nie powinno być konieczne, zwykle nie jest.
JackHasaKeyboard

111

Net :: HTTP jest wbudowany w Ruby, ale spójrzmy prawdzie w oczy, często łatwiej jest nie używać nieporęcznego stylu lat 80. i wypróbować alternatywę wyższego poziomu:


4
Lub ActiveResource, który jest dostarczany z Railsami!
Marnen Laibow-Koser

8
Chciałbym przestrzec przed tym, ponieważ dodasz więcej zależności do swojej aplikacji railsowej. Więcej zależności oznacza większe zużycie pamięci, a także potencjalnie większą powierzchnię ataku. Używanie Net::HTTPjest kłopotliwe, ale nie warto.
Jason Yeo

3
To powinna być zaakceptowana odpowiedź. Po co programować, kiedy można po prostu zainstalować wiele klejnotów?
omikes

5
@JasonYeo Zdecydowanie się nie zgadzam. Wprowadzenie zależności oznacza, że ​​nie wymyślasz na nowo koła i czerpiesz korzyści z ciężkiej pracy, którą inni już wykonali. Jeśli istnieje klejnot, który ułatwia życie, generalnie nie ma dobrego powodu, aby go nie używać.
Marnen Laibow-Koser

1
@JasonYeo Saga na lewym panelu miała miejsce tylko dlatego, że NPM źle prowadził swoje repozytorium i pozwolił autorowi usunąć wszystkie swoje pakiety. Właściwie zarządzane repozytorium pakietów tego nie robi (w każdym razie jest to OSS, więc możesz łatwo wykonać kopię lustrzaną, jeśli chcesz). To znaczy, że saga po lewej stronie nie jest argumentem przeciwko wprowadzeniu zależności w ogóle, ale raczej przeciwko złemu zarządzaniu repozytorium. Zgadzam się z twoim drugim punktem, że duża zależność, która robi o wiele więcej, niż potrzebujesz, może być przesadą w stosunku do wartości, którą zapewnia.
Marnen Laibow-Koser


82
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')

13

Wolę httpclient niż Net :: HTTP.

client = HTTPClient.new
puts client.get_content('http://www.example.com/index.html')

HTTParty to dobry wybór, jeśli tworzysz klasę, która jest klientem usługi. Jest to wygodny mixin, który daje 90% tego, czego potrzebujesz. Zobacz, jak krótcy są klienci Google i Twitter w przykładach .

I aby odpowiedzieć na twoje drugie pytanie: nie, nie umieściłbym tej funkcji w kontrolerze - zamiast tego użyłbym modelu, jeśli to możliwe, do enkapsulacji szczegółów (być może za pomocą HTTParty) i po prostu wywołałem go z kontrolera.


I w jaki sposób można bezpiecznie przekazać parametry w adresie URL? Np .: http: //www.example.com/index.html? Param1 = test1 i param2 = test2. Następnie muszę przeczytać z innych parametrów strony i przygotować odpowiedź. Ale jak mogę odczytać parametry?
user502052

Co masz na myśli, że musisz odczytać parametry drugiej strony? Jak to byłoby w ogóle możliwe? Co próbujesz osiągnąć?
Marnen Laibow-Koser


8

Oto kod, który działa, jeśli wykonujesz wywołanie interfejsu API REST za serwerem proxy:

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.