2009-04-01 51 views
13

Tengo una tabla en mi base de datos que contiene las direcciones URL de algunos sitios web. Tengo que abrir esas URL y verificar algunos enlaces en esas páginas. El problema es que algunas URL se redireccionan a otras URL. Mi lógica está fallando para tales URL.Obtener la URL redirigida desde la URL original

¿Hay alguna manera de pasar la secuencia URL original y recuperar la dirección URL redirigida?

Ejemplo: Estoy intentando con esta URL: http://individual.troweprice.com/public/Retail/xStaticFiles/FormsAndLiterature/CollegeSavings/trp529Disclosure.pdf

Se pone redirigido a éste: http://individual.troweprice.com/staticFiles/Retail/Shared/PDFs/trp529Disclosure.pdf

He intentado utilizar siguiente código:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Uris); 
req.Proxy = proxy; 
req.Method = "HEAD"; 
req.AllowAutoRedirect = false; 

HttpWebResponse myResp = (HttpWebResponse)req.GetResponse(); 
if (myResp.StatusCode == HttpStatusCode.Redirect) 
{ 
    MessageBox.Show("redirected to:" + myResp.GetResponseHeader("Location")); 
} 

Cuando ejecuto el el código de arriba me da HttpStatusCodeOk. Me sorprende por qué no está considerando una redirección. Si abro el enlace en Internet Explorer, se redireccionará a otra URL y se abrirá el archivo PDF.

¿Alguien me puede ayudar a entender por qué no funciona correctamente para la URL de ejemplo?

Por cierto, lo comprobé con la URL de Hotmail (http://www.hotmail.com) y devuelve correctamente la URL redirigida.

Gracias,

Respuesta

17

La URL que usted ha mencionado utiliza un redireccionamiento de JavaScript, que sólo volverá a dirigir un navegador. Entonces, no hay una manera fácil de detectar el redireccionamiento.

Para un correcto (código de estado HTTP y ubicación :) redirecciones, es posible que desee eliminar

req.AllowAutoRedirect = false; 

y obtener la URL final utilizando

myResp.ResponseUri 

ya que puede haber más de un redireccionamiento.

ACTUALIZACIÓN: Más aclaraciones en relación con las redirecciones:

Hay más de una forma de redirigir el navegador a otra URL.

La primera forma es usar un código de estado HTTP 3xx y el encabezado Ubicación :. Esta es la forma en que los dioses intentaron que las redirecciones de HTTP funcionen, y también se conoce como "la única forma verdadera". Este método funcionará en todos los navegadores y rastreadores.

Y luego están los caminos del diablo. Estos incluyen meta refresh, el encabezado Refresh: y JavaScript. Aunque estos métodos funcionan en la mayoría de los navegadores, definitivamente no se garantiza que funcionen y ocasionalmente provocan un comportamiento extraño (también conocido como breaking the back button).

La mayoría de los rastreadores web, incluido el robot de Google, ignoran estos métodos de redirección, y usted también. Si tiene absolutamente tiene para detectar todas las redirecciones, entonces debería analizar el HTML para las etiquetas META, buscar Refrescar: encabezados en la respuesta y evaluar Javascript. Buena suerte con el último.

+0

Extracción req.AllowAutoRedirect = false; no ayuda – user85594

+0

Entiendo tu punto de redireccionamiento de JavaScript, pero cuando uso myResp.ResponseUri.AbsoluteUri me da la URL original en lugar de redirigir una. ¿Hay alguna otra forma de obtener la URL redirigida? – user85594

+0

La URL en cuestión siempre devolverá la misma URL, porque no redirige. La * redirección * aparente es solo Javascript, y usted debería evaluar Javascript para detectarlo. –

0

Puede marcar Request.UrlReferrer.AbsoluteUri para ver de dónde vengo. Si eso no funciona, ¿puede pasar la URL anterior como parámetro de cadena de consulta?

+0

Cuando depuro el código req.Referer es nulo y myResp.ResponseUri.AbsoluteUri devuelve la URL original en lugar de la URL redirigida. No pude encontrar el método UrlReferrer disponible con el objeto Request. – user85594

-1

Hice este método usando su código y devuelve la URL redireccionada final.

 public string GetFinalRedirectedUrl(string url) 
    { 
     string result = string.Empty; 

     Uri Uris = new Uri(url); 

     HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Uris); 
     //req3.Proxy = proxy; 
     req.Method = "HEAD"; 
     req.AllowAutoRedirect = false; 

     HttpWebResponse myResp = (HttpWebResponse)req.GetResponse(); 
     if (myResp.StatusCode == HttpStatusCode.Redirect) 
     { 
      string temp = myResp.GetResponseHeader("Location"); 
      //Recursive call 
      result = GetFinalRedirectedUrl(temp); 
     } 
     else 
     { 
      result = url; 
     } 

     return result; 
    } 

Nota: myResp.ResponseUri no devuelve la URL final

0

Este código funciona para mí

var request = (HttpWebRequest)HttpWebRequest.Create(url); 
request.Method = "POST"; 
request.AllowAutoRedirect = true; 
request.ContentType = "application/x-www-form-urlencoded"; 
var response = request.GetResponse(); 

// Después de enviar la solicitud y la solicitud se espera para redirigir a alguna página de su sitio web, The response.ResponseUri.AbsoluteUri contiene esa url que incluye las cadenas de consulta // (www.yourwebsite.com/returnulr?r = "" ... y así sucesivamente)

Redirect(response.ResponseUri.AbsoluteUri); //then just do your own redirect. 

Esperanza esto ayuda

5

uso de este código para obtener redirigir url

public void GrtUrl(string url) 
    { 
     HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); 
     webRequest.AllowAutoRedirect = false; // IMPORTANT 

     webRequest.Timeout = 10000;   // timeout 10s 
     webRequest.Method = "HEAD"; 
     // Get the response ... 
     HttpWebResponse webResponse; 
     using (webResponse = (HttpWebResponse)webRequest.GetResponse()) 
     { 
      // Now look to see if it's a redirect 
      if ((int)webResponse.StatusCode >= 300 && (int)webResponse.StatusCode <= 399) 
      { 
       string uriString = webResponse.Headers["Location"]; 
       Console.WriteLine("Redirect to " + uriString ?? "NULL"); 
       webResponse.Close(); // don't forget to close it - or bad things happen! 
      } 

     } 

    } 
12

Esta función devolverá el destino final de un enlace - incluso si hay múltiples redirecciones. No tiene en cuenta los redireccionamientos basados ​​en JavaScript ni los redireccionamientos META. Observe que la solución anterior no se ocupó de las URL relativas absolutas &, dado que el encabezado LOCATION podría devolver algo como "/ newhome" que necesita combinar con la URL que sirvió esa respuesta para identificar el destino de la URL completa.

public static string GetFinalRedirect(string url) 
    { 
     if(string.IsNullOrWhiteSpace(url)) 
      return url; 

     int maxRedirCount = 8; // prevent infinite loops 
     string newUrl = url; 
     do 
     { 
      HttpWebRequest req = null; 
      HttpWebResponse resp = null; 
      try 
      { 
       req = (HttpWebRequest) HttpWebRequest.Create(url); 
       req.Method = "HEAD"; 
       req.AllowAutoRedirect = false; 
       resp = (HttpWebResponse)req.GetResponse(); 
       switch (resp.StatusCode) 
       { 
        case HttpStatusCode.OK: 
         return newUrl; 
        case HttpStatusCode.Redirect: 
        case HttpStatusCode.MovedPermanently: 
        case HttpStatusCode.RedirectKeepVerb: 
        case HttpStatusCode.RedirectMethod: 
         newUrl = resp.Headers["Location"]; 
         if (newUrl == null) 
          return url; 

         if (newUrl.IndexOf("://", System.StringComparison.Ordinal) == -1) 
         { 
          // Doesn't have a URL Schema, meaning it's a relative or absolute URL 
          Uri u = new Uri(new Uri(url), newUrl); 
          newUrl = u.ToString(); 
         } 
         break; 
        default: 
         return newUrl; 
       } 
       url = newUrl; 
      } 
      catch (WebException) 
      { 
       // Return the last known good URL 
       return newUrl; 
      } 
      catch (Exception ex) 
      { 
       return null; 
      } 
      finally 
      { 
       if (resp != null) 
        resp.Close(); 
      } 
     } while (maxRedirCount-- > 0); 

     return newUrl; 
    } 
+0

Tomé http://feeds.gawker.com/lifehacker/full como un ejemplo. Las herramientas de desarrollo de Chrome muestran una redirección 307 y el encabezado de ubicación establecido en https://feeds.feedburner.com/lifehacker/full. Pero cuando uso su código anterior, siempre obtengo un 200 OK. ¿Algunas ideas? – Howiecamp

+0

@Howiecamp Es muy probable que envíen respuestas diferentes basadas en User-Agent. Puede cambiar el Req.UserAgent para que parezca un navegador Chrome. –

0

que tenían el mismo problema y después tratando un montón que no podía conseguir lo que quería con HttpWebRequest así que utiliza la clase de navegador web para navegar hasta primera URL y entonces podría obtener la URL redirigida!

WebBrowser browser = new WebBrowser(); 
browser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.browser_Navigating); 
string urlToNavigate = "your url"; 
browser.Navigate(new Uri(urlToNavigate)); 

y luego navegando puede obtener su URL redirigida. Tenga cuidado de que se produzca el controlador de eventos browser_Navigating primera vez, e.url es la misma URL que utilizó para comenzar a navegar url para que pueda redirigido de la segunda llamada

private void browser_Navigating(object sender, WebBrowserNavigatingEventArgs e) 
{ 
    Uri uri = e.Url; 
} 
Cuestiones relacionadas