2009-09-05 19 views
8

Dado que una URL A que se redirecciona a un sitio web de terceros B, en mi aplicación necesito encontrar la URL B para la url A dada e insertarla en la base de datos, esto puede ser aplicación de Windows o web o de cualquier manera es más rápido y más fácil de usar C#! Gracias!Una forma de descubrir la redirección URL

P.S. No necesito el código para insertar en DB.

+2

depende de cómo funciona la redirección. ¿Lado del servidor? ¿Del lado del cliente (es decir, JS)? Intente buscar la URL con los envoltorios http C# y siguiendo cualquier 301s/302s. Si tiene suerte, puede que incluso haya una biblioteca que lo haga por usted. ¿Qué pasa si B redirige a C? ¿Quieres almacenar B o C? ¿Cuán lejos seguirás los redireccionamientos? ¿Qué pasa si C se redirige a B? Asegúrate de evitar los bucles infinitos de redirección al realizar un seguimiento de las direcciones que has visitado o establecer un límite de redirección (que creo que es la forma en que Firefox/Chrome maneja este problema). –

+0

El ejemplo del lado del servidor estaría bien ... esto es solo una herramienta para extraer datos (es decir, la URL final) por lo que no tiene que ser elegante ... ¡se puede hacer de cualquier manera! "A" siempre se redireccionará a "B" y no hay más redirección para pasar más lejos desde allí que es un hecho establecido. –

+0

El código del lado del cliente no duele demasiado ... Supongo que una aplicación de formulario de victoria con una instancia de IE dentro debería hacer el trabajo ... simplemente no estoy seguro –

Respuesta

10

WebRequest sigue redirecciones sin intervención del usuario, por lo que si las redirecciones están utilizando 301/302 códigos de estado, entonces el siguiente trabajo

WebRequest request = WebRequest.Create(destination); 
WebResponse response = request.GetResponse(); 
Console.WriteLine(response.ResponseUri); 

Si las redirecciones se crean utilizando JavaScript o http-equiv etiquetas meta, entonces' haciendo para tener que analizar la página y buscarlos. El paquete de agilidad de HTML es probablemente la mejor manera de hacerlo.

Para llevar esto un poco más lo que sigue es una clase que resolverá de forma manual los principales códigos de estado de redirección HTTP, la construcción de una historia, ya que va

/// <summary> 
/// Digs through HTTP redirects until a non-redirected URL is found. 
/// </summary> 
public class Digger 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="Digger"/> class. 
    /// </summary> 
    public Digger() : this(20) 
    {    
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="Digger"/> class. 
    /// </summary> 
    /// <param name="maximumDepth">The maximum depth of redirects to parse.</param> 
    public Digger(int maximumDepth) 
    { 
     this.MaximumDepth = maximumDepth; 
    } 

    /// <summary> 
    /// Gets the maximum depth of redirects to parse. 
    /// </summary> 
    /// <value>The maximum depth of redirects to parse.</value> 
    public int MaximumDepth 
    { 
     get; 
     private set; 
    } 

    /// <summary> 
    /// Resolves any redirects at the specified URI. 
    /// </summary> 
    /// <param name="destination">The initial URI.</param> 
    /// <returns>The URI after resolving any HTTP redirects.</returns> 
    public Uri Resolve(Uri destination) 
    { 
     List<Uri> redirectHistory = new List<Uri>(); 
     return this.Resolve(destination, redirectHistory); 
    } 

    /// <summary> 
    /// Resolves any redirects at the specified URI. 
    /// </summary> 
    /// <param name="destination">The initial URI.</param> 
    /// <param name="redirectHistory">A collection of <see cref="Uri"/> objects representing the redirect history.</param> 
    /// <returns>The URI after resolving any HTTP redirects.</returns> 
    public Uri Resolve(Uri destination, ICollection<Uri> redirectHistory) 
    { 
     redirectHistory.Add(destination); 
     return this.Resolve(destination, this.MaximumDepth, redirectHistory); 
    } 

    /// <summary> 
    /// Resolves any redirects at the specified URI. 
    /// </summary> 
    /// <param name="destination">The initial URI.</param> 
    /// <param name="hopsLeft">The maximum number of redirects left to follow.</param> 
    /// <param name="redirectHistory">A collection of <see cref="Uri"/> objects representing the redirect history.</param> 
    /// <returns>The URI after resolving any HTTP redirects.</returns> 
    private Uri Resolve(Uri destination, int hopsLeft, ICollection<Uri> redirectHistory) 
    { 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destination); 
     request.AllowAutoRedirect = false; 
     request.Method = "HEAD"; 

     HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

     Uri resolvedUri; 

     if (response.StatusCode == HttpStatusCode.Redirect || 
      response.StatusCode == HttpStatusCode.Moved || 
      response.StatusCode == HttpStatusCode.MovedPermanently) 
     { 
      if (hopsLeft > 0) 
      { 
       Uri redirectUri = new Uri(response.GetResponseHeader("Location")); 
       if (redirectHistory.Contains(redirectUri)) 
       { 
        throw new Exception("Recursive redirection found"); 
       } 

       redirectHistory.Add(redirectUri); 
       resolvedUri = this.Resolve(redirectUri, hopsLeft - 1, redirectHistory); 
      } 
      else 
      { 
       throw new Exception("Maximum redirect depth reached"); 
      } 
     } 
     else 
     { 
      resolvedUri = response.ResponseUri; 
     } 

     return resolvedUri;    
    } 
} 
+0

¡Gracias funciona a la perfección! –

+0

Esto no funcionará si el encabezado de la ubicación contiene un URI relativo. Yo creo: 'Uri redirectUri; if (! Uri.TryCreate (location, UriKind.Absolute, out redirectUri)) {if (! Uri.TryCreate (response.ResponseUri, location, out redirectUri)) {throw new WebException ("Redirect no válido"); }} 'funcionará en casos más/más/(todos si las estrellas se alinean), pero todavía no lo han probado. –

+0

¡Qué magnífica respuesta! – Ikaso

0
Uri MyUrl = Request.UrlReferrer; 
Response.Write("Referrer URL Port: " + Server.HtmlEncode(MyUrl.Port.ToString()) + "<br>"); 
Response.Write("Referrer URL Protocol: " + Server.HtmlEncode(MyUrl.Scheme) + "<br>"); 

Como lo que entiendo de su pregunta se puede utilizar un código como este para que pueda ver la url anterior y guardarlo en db mediante LINQ u otros métodos de ADO.NET.

Supongo que sabe cómo guardar registros en db con LINQ. Si no lo hace, por favor, siga este enlace: LINQ to SQL - 5 Minute Overview

Espero que ayude.

Cuestiones relacionadas