Comment faire une requête HTTP en utilisant Ruby on Rails?


235

Je voudrais prendre des informations d'un autre site Web. Par conséquent (peut-être) je devrais faire une demande à ce site Web (dans mon cas, une demande HTTP GET) et recevoir la réponse.

Comment puis-je faire cela dans Ruby on Rails?

Si c'est possible, est-ce une approche correcte à utiliser dans mes contrôleurs?

Réponses:


330

Vous pouvez utiliser la Net::HTTPclasse de 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
que signifie le «req» ici?
sixty4bit

18
cela signifie demande
Arthur Collé

1
On dirait que cela pourrait être une demande de blocage, n'est-ce pas?
Scott Eisenberg

où mettre la clé api?
user1735921

1
Ajoutons simplement que le www. ne devrait pas être nécessaire, ce n'est généralement pas le cas.
JackHasaKeyboard du

111

Net :: HTTP est intégré à Ruby, mais avouons-le, il est souvent plus facile de ne pas utiliser son style encombrant des années 1980 et d'essayer une alternative de niveau supérieur:


4
Ou ActiveResource, qui vient avec Rails!
Marnen Laibow-Koser

8
Je voudrais mettre en garde contre cela, car vous ajouterez plus de dépendances à votre application rails. Plus de dépendances signifie plus de consommation de mémoire et également une surface d'attaque potentiellement plus grande. L'utilisation Net::HTTPest lourde mais le compromis n'en vaut pas la peine.
Jason Yeo

3
Ce devrait être la réponse acceptée. Pourquoi programmer quand vous pouvez simplement installer de nombreuses gemmes?
omikes

5
@JasonYeo Fortement en désaccord. L'introduction de dépendances signifie que vous ne réinventez pas la roue et que vous bénéficiez du travail acharné que d'autres ont déjà accompli. S'il existe une gemme qui vous facilite la vie, il n'y a généralement aucune bonne raison de ne pas l'utiliser.
Marnen Laibow-Koser

1
@JasonYeo La saga du leftpad ne s'est produite que parce que NPM a mal géré son référentiel et laissé l'auteur supprimer tous ses packages. Les dépôts de packages correctement gérés ne le font pas (et de toute façon, c'est OSS, vous pouvez donc facilement le mettre en miroir si vous le souhaitez). C'est-à-dire que la saga du leftpad n'est pas un argument contre l'introduction de dépendances en général, mais plutôt contre une mauvaise gestion du repo. Je suis d'accord avec votre autre point, qu'une grande dépendance qui fait bien plus que ce dont vous avez besoin peut être exagérée pour la valeur qu'elle fournit.
Marnen Laibow-Koser

92

OpenURI est le meilleur; c'est aussi simple que

require 'open-uri'
response = open('http://example.com').read

10
Il est important de prévenir, cela open-urine suivra pas les redirections.
yagooar

3
@yagooar qui est génial, empêche les redirections malveillantes commefile:///etc/passwd
gertas

1
Veuillez noter qu'il ne fermera pas la connexion. Utilisez stackoverflow.com/a/4217269/820501
ShockwaveNN

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

Je préfère httpclient à Net :: HTTP.

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

HTTParty est un bon choix si vous créez une classe qui est un client pour un service. C'est un mixin pratique qui vous donne 90% de ce dont vous avez besoin. Voyez à quel point les clients Google et Twitter sont courts dans les exemples .

Et pour répondre à votre deuxième question: non, je ne mettrais pas cette fonctionnalité dans un contrôleur - j'utiliserais plutôt un modèle si possible pour encapsuler les détails (peut-être en utilisant HTTParty) et simplement l'appeler à partir du contrôleur.


Et comment est-il possible de passer des paramètres en toute sécurité dans l'URL? Par exemple: http: //www.example.com/index.html? Param1 = test1 & param2 = test2. Ensuite, je dois lire les autres paramètres du site Web et préparer la réponse. Mais comment lire les paramètres?
user502052

Que voulez-vous dire, vous devez lire les paramètres de l'autre site Web? Comment serait-ce possible? Qu'essayez-vous d'accomplir?
Marnen Laibow-Koser

8

Mes deux façons préférées de saisir le contenu des URL sont OpenURI ou Typhoeus .

OpenURI parce qu'il est partout et Typhoeus parce qu'il est très flexible et puissant.


8

Voici le code qui fonctionne si vous effectuez un appel API REST derrière 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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.