Come effettuare una richiesta HTTP utilizzando Ruby on Rails?


235

Vorrei prendere informazioni da un altro sito Web. Pertanto (forse) dovrei fare una richiesta a quel sito Web (nel mio caso una richiesta GET HTTP) e ricevere la risposta.

Come posso farlo in Ruby on Rails?

Se è possibile, è un approccio corretto da utilizzare nei miei controller?

Risposte:


330

Puoi usare la Net::HTTPclasse di 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
cosa significa "req" qui?
sixty4bit

18
significa richiesta
Arthur Collé,

1
Sembra che questa potrebbe essere una richiesta di blocco, no?
Scott Eisenberg,

dove mettere la chiave API?
user1735921

1
Aggiungo solo che il www. non dovrebbe essere necessario, in genere non lo è.
JackHasaKeyboard

111

Net :: HTTP è integrato in Ruby, ma ammettiamolo, spesso è più facile non usare il suo ingombrante stile degli anni '80 e provare un'alternativa di livello superiore:


4
O ActiveResource, fornito con Rails!
Marnen Laibow-Koser,

8
Vorrei mettere in guardia dal farlo in quanto aggiungerai più dipendenze alla tua app rotaie. Più dipendenze significano un maggiore consumo di memoria e anche una superficie di attacco potenzialmente più ampia. L'uso Net::HTTPè ingombrante ma il compromesso non ne vale la pena.
Jason Yeo,

3
Questa dovrebbe essere la risposta accettata. Perché programmare quando puoi semplicemente installare molte gemme?
omike

5
@JasonYeo Sono in forte disaccordo. L'introduzione di dipendenze significa che non reinventare la ruota e trarre vantaggio dal duro lavoro che altri hanno già fatto. Se esiste una gemma che ti semplifica la vita, generalmente non c'è motivo di non usarla.
Marnen Laibow-Koser,

1
@JasonYeo La saga del leftpad è avvenuta solo perché l'NPM ha gestito male il suo repository e ha permesso all'autore di eliminare tutti i suoi pacchetti. I repository di pacchetti gestiti correttamente non lo fanno (e comunque è OSS, quindi puoi facilmente eseguire il mirroring se lo desideri). Cioè, la saga del leftpad non è un argomento contro l'introduzione di dipendenze in generale, ma piuttosto contro la gestione scadente del repository. Sono d'accordo con l'altro tuo punto, sul fatto che una grande dipendenza che fa molto più del necessario può essere eccessiva per il valore che fornisce.
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

Preferisco httpclient su Net :: HTTP.

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

HTTParty è una buona scelta se stai creando una classe che è un client per un servizio. È un comodo mixin che ti dà il 90% di ciò di cui hai bisogno. Guarda quanto sono brevi i client Google e Twitter negli esempi .

E per rispondere alla tua seconda domanda: no, non inserirei questa funzionalità in un controller: utilizzerei invece un modello, se possibile, per incapsulare i particolari (forse usando HTTParty) e semplicemente chiamarlo dal controller.


E come è possibile passare parametri sicuri nell'URL? Ad esempio: http: //www.example.com/index.html? Param1 = test1 & param2 = test2. Quindi ho bisogno di leggere gli altri parametri del sito Web e preparare la risposta. Ma come posso leggere i parametri?
user502052

Cosa vuoi dire, devi leggere i parametri dell'altro sito web? Come sarebbe possibile? Cosa stai cercando di ottenere?
Marnen Laibow-Koser,

8

I miei preferiti due modi per afferrare il contenuto di URL sono o OpenURI o Tifeo .

OpenURI perché è ovunque e Typhoeus perché è molto flessibile e potente.


8

Ecco il codice che funziona se si sta effettuando una chiamata api REST dietro un 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.