2011-01-02 21 views
191

Me gustaría obtener información de otro sitio web. Por lo tanto, tal vez debería hacer una solicitud a ese sitio web (en mi caso, una solicitud HTTP GET) y recibir la respuesta.¿Cómo hacer una solicitud HTTP usando Ruby on Rails?

¿Cómo puedo hacer esto en Ruby on Rails?

Si es posible, ¿es un método correcto de usar en mis controladores?

Respuesta

278

Se puede utilizar la clase de 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 
+0

lo que quiere decir el 'req' aquí? – sixty4bit

+10

significa solicitud –

+1

Parece que esto podría ser una solicitud de bloqueo, ¿no es así? –

62
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') 
90

Net :: HTTP está integrado en Ruby, pero seamos sinceros, a menudo es más fácil no a utilizar su estilo de 1980 engorrosos y tratar una alternativa de mayor nivel:

+3

¡O ActiveResource, que viene con Rails! –

+5

Me gustaría advertirle que no lo haga ya que agregará más dependencias a su aplicación de rieles. Más dependencias significa más consumo de memoria y también una superficie de ataque potencialmente más grande. Usar 'Net :: HTTP' es engorroso, pero la compensación no vale la pena. –

+1

Esta debería ser la respuesta aceptada. ¿Por qué programar cuando puedes simplemente instalar muchas gemas? – oMiKeY

12

prefiero httpclient sobre Net :: HTTP.

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

HTTParty es una buena opción si está realizando una clase que es cliente de un servicio. Es una combinación conveniente que le brinda el 90% de lo que necesita. Vea qué tan cortos son los clientes de Google y Twitter en el examples.

Y para responder a su segunda pregunta: no, no pondría esta funcionalidad en un controlador - en su lugar usaría un modelo para encapsular los detalles (quizás usando HTTParty) y simplemente lo llamaría desde el controlador .

+0

¿Y cómo es posible pasar parámetros seguros en la URL? Ejemplo: http: //www.example.com/index.html? Param1 = test1 & param2 = test2. Luego, necesito leer los otros parámetros del sitio web y preparar la respuesta. Pero, ¿cómo puedo leer los parámetros? – user502052

+0

¿Qué quiere decir con que necesita leer los parámetros del otro sitio web? ¿Cómo sería eso posible? ¿Qué estás intentando lograr? –

+0

Para obtener más información, consulte: https://github.com/nahi/httpclient – Abdo

8

Mis dos formas favoritas de captar el contenido de las URL son OpenURI o Typhoeus.

OpenURI porque está en todas partes, y Typhoeus porque es muy flexible y potente.

81

OpenURI es el mejor; es tan simple como

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

'response = open (" http://example.com/ ") .read' – hlcs

+8

Es importante advertir que' open-uri 'no seguirá los redireccionamientos. – yagooar

+3

@yagooar que es genial, evita redirecciones maliciosas como 'file: /// etc/passwd' – gertas

6

Aquí está el código que funciona si usted está haciendo una llamada a la API REST detrás de 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