2011-05-03 12 views
23

De acuerdo con Facebook API gráfica se puede solicitar una imagen de perfil de usuario con esto (ejemplo):Consigue redirigir de una URL en Ruby

https://graph.facebook.com/1489686594/picture 

Pero el URL de la imagen real de la relación anterior es:

http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs356.snc4/41721_1489686594_527_q.jpg

Si escribe el primer enlace en su navegador, lo redirigirá al segundo enlace.

¿Hay alguna forma de obtener la URL completa (segundo enlace) con Ruby/Rails, solo conociendo la primera URL?

(Esta es una repetición de this question, pero para Ruby)

+0

posible duplicado de [¿Cómo puedo obtener la URL final después de los redireccionamientos con Ruby?] (Http: // stackoverflow.com/questions/4867652/how-can-i-get-the-final-url-after-redirects-using-ruby) – lulalala

+0

posible duplicado de [En Ruby, ¿cómo obtengo la URL de destino de una URL acortada?] (http://stackoverflow.com/questions/5532362/in-ruby-how-do-i-get-the-destination-url-of-a-shortened-url) –

+0

Utilicé [final_redirect_url] (https: // rubygems .org/gems/final_redirect_url) gem para obtener la url redireccionada final. – Indyarocks

Respuesta

13

Puede utilizar Net :: HTTP y leer el encabezado de la respuesta Location:

require 'net/http' 
require 'uri' 

url = URI.parse('http://www.example.com/index.html') 
res = Net::HTTP.start(url.host, url.port) {|http| 
    http.get('/index.html') 
} 
res['location'] 
+3

Puede usar url.request_uri en lugar de '/index.html'. – FelipeC

+2

¿Qué pasa si hay más de una redirección? ¿conseguirá el último? o solo el primero? – Sean

9

Tienes HTTPS URL allí, por lo que tendrá que manejar ...

require 'net/http' 
require 'net/https' if RUBY_VERSION < '1.9' 
require 'uri' 

u = URI.parse('https://graph.facebook.com/1489686594/picture') 

h = Net::HTTP.new u.host, u.port 
h.use_ssl = u.scheme == 'https' 

head = h.start do |ua| 
    ua.head u.path 
end 

puts head['location'] 
+0

¿Y cuando el u.path está vacío? Ejemplo: URI.parse ('http://url.com') .path. Gracias – Luccas

+0

En realidad, en su ejemplo 'u.path' será' "url.com" 'porque' "url.com" 'es un URI válido, es solo que como URI no contiene host, puerto o esquema, es visto como toda la ruta por 'URI.parse'. Si desea que los datos se interpreten como un nombre de host, deberá realizar pasos adicionales antes de pasarlos a 'URI.parse' – smathy

+0

, pero con' http: // 'antes de' url.com' devuelve la ruta vacía – Luccas

0

Sí, cabecera de respuesta "Lugar" os digo la URL de la imagen real.

Sin embargo, si utiliza la imagen como imagen de perfil del usuario en su sitio, le recomendamos que utilice la URL de estilo "https://graph.facebook.com/:user_id/picture" en lugar de la URL de la imagen real. De lo contrario, sus usuarios verán muchas imágenes "no encontradas" o imágenes de perfil desactualizadas en el futuro.

Acabas de poner "https://graph.facebook.com/:user_id/picture" como el atributo "src" de la etiqueta "img". El navegador obtiene la imagen actualizada del usuario.

ps. Tengo tales problemas en mi sitio con Twitter & Yahoo! OpenID ahora ..

32

Esto ya fue contestada correctamente, pero hay una manera mucho más simple:

res = Net::HTTP.get_response(URI('https://graph.facebook.com/1489686594/picture')) 
res['location'] 
+2

+1 para publicar una solución que ocupa menos del 20% del espacio de las otras, pero logra lo mismo. –

+3

Esto es bueno, pero solo sigue un nivel de redirección :( – markquezada

+0

Genial, esta es la solución que me gusta. –

2

Sé que esto es una vieja pregunta, pero voy a añadir esta respuesta para la posteridad:

La mayoría de las soluciones que he visto solo siguen una sola redirección. En mi caso, tuve que seguir múltiples redireccionamientos para obtener la URL de destino final real. Solía ​​Curl (a través de la Curb gem) de esta manera:

result = Curl::Easy.perform(url) do |curl| 
    curl.head = true 
    curl.follow_location = true 
end 
result.last_effective_url 
1

Puede comprobar el código de estado de respuesta y obtener la URL final de forma recursiva usando algo como get_final_redirect_url método:

require 'net/http' 

    def get_final_redirect_url(url, limit = 10) 
    uri = URI.parse(url) 
    response = ::Net::HTTP.get_response(uri) 
    if response.class == Net::HTTPOK 
     return uri 
    else 
     redirect_location = response['location'] 
     location_uri = URI.parse(redirect_location) 
     if location_uri.host.nil? 
     redirect_location = uri.scheme + '://' + uri.host + redirect_location 
     end 
     warn "redirected to #{redirect_location}" 
     get_final_redirect_url(redirect_location, limit - 1) 
    end 
    end 

que estaba enfrentando el mismo problema . Lo resolví y construí una gema final_redirect_url a su alrededor, para que todos puedan beneficiarse de ella.

Puede encontrar los detalles sobre los usos here.

Cuestiones relacionadas