Получение перенаправленного URL из исходного URL-адреса
У меня есть таблица в моей базе данных, содержащая URL-адреса некоторых веб-сайтов. Мне нужно открыть эти URL-адреса и проверить некоторые ссылки на этих страницах. Проблема в том, что некоторые URL-адреса перенаправляются на другие URL-адреса. Моя логика не подходит для таких URL-адресов.
Есть ли способ передать исходную строку URL-адреса и вернуть перенаправленный URL-адрес?
Пример: я пытаюсь использовать этот URL:
http://individual.troweprice.com/public/Retail/xStaticFiles/FormsAndLiterature/CollegeSavings/trp529Disclosure.pdf
Он перенаправляется на этот:
http://individual.troweprice.com/staticFiles/Retail/Shared/PDFs/trp529Disclosure.pdf
Я попытался использовать следующий код:
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"));
}
Когда я выполняю код выше, он дает мне HttpStatusCodeOk
. Я удивлен, почему он не рассматривает это перенаправление. Если я открою ссылку в Internet Explorer, она перенаправит другой URL-адрес и откроет файл PDF.
Может кто-нибудь помочь мне понять, почему он не работает правильно для URL-адреса примера?
Кстати, я проверил с URL Hotmail (http://www.hotmail.com), и он правильно возвращает перенаправленный URL.
Спасибо,
Ответы
Ответ 1
В указанном вами URL-адресе используется перенаправление JavaScript, которое будет перенаправлять браузер. Таким образом, нет простого способа обнаружить перенаправление.
Для правильной (перенаправления HTTP-кода и местоположения HTTP-кода) вы можете удалить
req.AllowAutoRedirect = false;
и получите окончательный URL-адрес, используя
myResp.ResponseUri
поскольку может быть более одного перенаправления.
ОБНОВЛЕНИЕ: больше разъяснений относительно перенаправления:
Существует несколько способов перенаправления браузера на другой URL.
Первый способ - использовать код состояния HTTP 3xx и заголовок Location:. Это то, как боги предполагали, что перенаправление HTTP работает, и также известно как "один истинный путь". Этот метод будет работать на всех браузерах и сканерах.
И тогда есть пути дьявола. К ним относятся meta refresh, заголовок Refresh: и JavaScript. Хотя эти методы работают в большинстве браузеров, они определенно не гарантированно работают, а иногда приводят к странному поведению (ака. нарушение кнопки назад).
Большинство веб-сканеров, включая робота Googlebot, игнорируют эти методы перенаправления, и вы тоже должны. Если вам абсолютно необходимо обнаружить все переадресации, вам придется анализировать HTML-теги META, искать Refresh: заголовки в ответе и оценивать Javascript. Удачи с последним.
Ответ 2
Эта функция вернет конечный пункт назначения ссылки - даже если есть несколько перенаправлений. Он не учитывает переадресацию на основе JavaScript или перенаправление метаданных. Обратите внимание, что предыдущее решение не касалось Абсолютных и Относительных URL-адресов, поскольку заголовок LOCATION может возвращать что-то вроде "/newhome", которое вам нужно объединить с URL-адресом, который служил для этого ответа, чтобы идентифицировать полный URL-адрес.
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 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;
}
Ответ 3
используйте этот код, чтобы перенаправить 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 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!
}
}
}
Ответ 4
Вы можете проверить Request.UrlReferrer.AbsoluteUri, чтобы узнать, откуда я пришел. Если это не сработает, вы можете передать старый url в качестве параметра строки запроса?
Ответ 5
Этот код работает для меня
var request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.AllowAutoRedirect = true;
request.ContentType = "application/x-www-form-urlencoded";
var response = request.GetResponse();
//После отправки запроса и ожидаемого перенаправления запроса на какую-либо страницу вашего веб-сайта ответ. ResponseUri.AbsoluteUri содержит этот url, включая строки запроса
// (www.yourwebsite.com/returnulr?r = ""... и т.д.)
Redirect(response.ResponseUri.AbsoluteUri); //then just do your own redirect.
Надеюсь, что это поможет
Ответ 6
У меня была такая же проблема, и после многих попыток я не смог получить то, что хотел с HttpWebRequest, поэтому я использовал класс веб-браузера для перехода к первому URL-адресу, а затем я мог получить перенаправленный URL-адрес!
WebBrowser browser = new WebBrowser();
browser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.browser_Navigating);
string urlToNavigate = "your url";
browser.Navigate(new Uri(urlToNavigate));
то при навигации вы можете получить свой перенаправленный URL. Будьте осторожны, чтобы первый обработчик события browser_Navigating выполнял, e.url - это тот же URL-адрес, который вы использовали для начала просмотра, чтобы вы могли перенаправить URL-адрес при втором вызове
private void browser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
Uri uri = e.Url;
}
Ответ 7
Я использовал этот метод, используя ваш код, и он возвращает окончательный перенаправленный URL.
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;
}
Примечание: myResp.ResponseUri не возвращает конечный URL