2009-04-01 7 views
13

J'ai une table dans ma base de données qui contient les URL de certains sites Web. Je dois ouvrir ces URL et vérifier certains liens sur ces pages. Le problème est que certaines URL sont redirigées vers d'autres URL. Ma logique échoue pour de telles URL.Récupération de l'URL redirigée à partir de l'URL d'origine

Existe-t-il un moyen par lequel je peux transmettre ma chaîne d'URL d'origine et récupérer l'URL redirigée?

Exemple: Je suis en train avec cette URL: http://individual.troweprice.com/public/Retail/xStaticFiles/FormsAndLiterature/CollegeSavings/trp529Disclosure.pdf

Il est redirigé vers celui-ci: http://individual.troweprice.com/staticFiles/Retail/Shared/PDFs/trp529Disclosure.pdf

J'ai essayé d'utiliser le code suivant:

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")); 
} 

Lorsque j'exécute la le code ci-dessus me donne HttpStatusCodeOk. Je suis surpris de voir pourquoi il ne s'agit pas d'une redirection. Si j'ouvre le lien dans Internet Explorer, il redirigera vers une autre URL et ouvrira le fichier PDF.

Quelqu'un peut-il m'aider à comprendre pourquoi cela ne fonctionne pas correctement pour l'exemple d'URL? D'ailleurs, j'ai vérifié avec l'URL de Hotmail (http://www.hotmail.com) et il renvoie correctement l'URL redirigée.

Merci,

Répondre

17

L'URL mentionné utilise une redirection JavaScript, qui ne redirige un navigateur. Il n'y a donc pas de moyen facile de détecter la redirection.

Pour bon (Code d'état HTTP et emplacement :) réoriente, vous pouvez supprimer

req.AllowAutoRedirect = false; 

et obtenir l'URL finale à l'aide

myResp.ResponseUri 

comme il peut y avoir plus d'une redirection.

MISE À JOUR: Plus d'éclaircissements au sujet de redirections:

Il y a plus d'une façon de rediriger un navigateur vers une autre URL. La première consiste à utiliser un code d'état HTTP 3xx et l'en-tête Location:. C'est la façon dont les dieux ont prévu que les redirections HTTP fonctionnent, et est également connu comme "le seul vrai chemin". Cette méthode fonctionnera sur tous les navigateurs et les robots d'exploration.

Et puis il y a les voies du diable. Ceux-ci incluent meta refresh, l'en-tête Refresh: et JavaScript. Bien que ces méthodes fonctionnent dans la plupart des navigateurs, elles ne sont certainement pas garanties de fonctionner, et entraînent parfois un comportement étrange (aka breaking the back button).

La plupart des robots d'indexation Web, y compris Googlebot, ignorent ces méthodes de redirection, et vous aussi. Si vous avez absolument pour détecter toutes les redirections, vous devrez alors analyser le code HTML pour les balises META, rechercher Refresh: en-têtes dans la réponse et évaluer Javascript. Bonne chance avec le dernier.

+0

Suppression req.AllowAutoRedirect = false; n'aide pas – user85594

+0

Je comprends votre point de javascript redirection, mais quand j'utilise myResp.ResponseUri.AbsoluteUri il me donne l'URL d'origine au lieu d'un redirigé. Y a-t-il un autre moyen d'obtenir l'URL redirigée? – user85594

+0

L'URL en question renvoie toujours la même URL, car elle ne redirige pas. La redirection * apparente * n'est que Javascript, et vous devrez évaluer Javascript pour le détecter. –

0

Vous pouvez consulter Request.UrlReferrer.AbsoluteUri pour voir d'où je viens. Si cela ne fonctionne pas, pouvez-vous passer l'ancien URL comme paramètre de chaîne de requête?

+0

Lorsque je débogue le code req.Referer est null et myResp.ResponseUri.AbsoluteUri renvoie l'URL d'origine au lieu de l'URL redirigée. Impossible de trouver la méthode UrlReferrer disponible avec l'objet Demande. – user85594

-1

J'ai fait cette méthode en utilisant votre code et il retourne l'URL redirigée finale.

 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; 
    } 

Note: myResp.ResponseUri ne retourne pas l'URL finale

0

Ce code fonctionne pour moi

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

// Après l'envoi de la demande et la demande devrait rediriger vers la page une de votre site Web, le response.ResponseUri.AbsoluteUri contient cette URL, y compris les chaînes de requête // (www.yourwebsite.com/returnulr?r = "" ... et ainsi de suite)

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

Hope this helps

5

utiliser ce code pour obtenir la redirection 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

Cette fonction retourne la destination finale d'un lien - même s'il y a plusieurs redirections. Il ne tient pas compte des redirections JavaScript ou des redirections META. Notez que la solution précédente ne traitait pas les URL relatives & absolues, puisque l'en-tête LOCATION pouvait renvoyer quelque chose comme "/ newhome" que vous devez combiner avec l'URL qui a servi cette réponse pour identifier la destination URL complète.

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

J'ai pris http://feeds.gawker.com/lifehacker/full comme exemple. Les outils de développement Chrome affichent une redirection 307 et l'en-tête de lieu est défini sur https://feeds.feedburner.com/lifehacker/full. Mais quand j'utilise votre code ci-dessus, je reçois toujours un 200 OK. Des idées? – Howiecamp

+0

@Howiecamp Très probablement, ils envoient des réponses différentes basées sur User-Agent. Vous pouvez changer le req.UserAgent pour qu'il ressemble à un navigateur Chrome. –

0

J'ai eu le même problème et après tryin beaucoup je ne pouvais pas obtenir ce que je voulais avec HttpWebRequest donc j'utilisé la classe de navigateur Web pour accéder à la première url puis je pourrais obtenir l'URL redirigée!

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

puis en naviguant, vous pouvez obtenir votre URL redirigé. Veillez à ce que la première fois gestionnaire d'événements browser_Navigating se produit, e.url est la même URL que vous avez utilisé pour commencer la navigation de sorte que vous pouvez redirigés url sur le deuxième appel

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