【问题标题】:A way to figure out redirection URL一种计算重定向 URL 的方法
【发布时间】:2010-11-25 20:11:42
【问题描述】:

给定一个被重定向到第 3 方网站 B 的 URL A,在我的应用程序中,我需要找出给定 URL A 的 URL B 并将其插入 DB,这可以是 Windows 应用程序或 Web 或任何方式使用 C# 更快更容易! 谢谢!

附:我不需要将代码插入数据库。

【问题讨论】:

  • 取决于重定向的工作方式。服务器端?客户端(即 JS)?尝试使用 C# 具有的任何 http 包装器获取 URL,并遵循任何 301s/302s。如果你幸运的话,甚至可能有一个图书馆可以为你做这件事。如果 B 重定向到 C 怎么办?您要存储 B 还是 C?您将遵循重定向多远?如果 C 重定向到 B 怎么办?通过跟踪您访问过的地址或设置重定向限制(我认为这是 Firefox/Chrome 处理此问题的方式),确保避免无限重定向循环。
  • 服务器端的例子很好......这只是一个提取数据的工具(即最终 URL),所以不必花哨......可以以任何方式完成! “A”将始终重定向到“B”,并且不再有重定向发生,这是一个既定事实。
  • 客户端代码也没有什么坏处......我假设一个带有 IE 实例的 win 表单应用程序应该可以完成这项工作......只是不确定
  • 简单来说,您想知道用户从哪里来并落入您的网站?而已? Request.ServerVariables("HTTP_REFERER")?
  • 只是为了澄清这是 jsuta 工具假设我有一个 URL www.abc.com 当在内部(从他们自己的服务器)键入时重定向到第 3 方站点,即 www.def.com 和两者URL 与我自己的网站没有任何关联...在工具中,我应该给它第一个 URL,即 www.abc.coma,它应该给我的结果是 www.def.com,就是这样!推荐人 wlogic 仅在最终 URL 是我自己的站点的情况下才有效,而事实并非如此。

标签: c# url redirect


【解决方案1】:

WebRequest 在没有用户干预的情况下跟踪重定向,因此如果重定向使用 301/302 状态代码,则以下将起作用

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

如果重定向是使用 javascript 或 HTTP-Equiv 元标记创建的,那么您就必须解析页面并查找它们。 HTML 敏捷包可能是最好的方法。

为了更进一步,下面是一个类,它将手动解析主要的 HTTP 重定向状态代码,建立一个历史记录

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

【讨论】:

  • 如果 Location 标头包含相对 URI,这将不起作用。我相信:Uri redirectUri; if (!Uri.TryCreate(location, UriKind.Absolute, out redirectUri)) { if (!Uri.TryCreate(response.ResponseUri, location, out redirectUri)) { throw new WebException("Invalid redirect"); } } 将适用于更多/大多数/(如果星星对齐)情况,但尚未彻底测试。
  • 这个解决方案很简单。谢谢
【解决方案2】:
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>");

正如我从您的问题中了解到的,您可以使用这样的代码,这样您就可以看到以前的 url 并使用 Linq 或其他 ADO.NET 方法将其保存到 db 中。

我假设您知道如何使用 LINQ 将记录保存在数据库中。如果您不这样做,请点击此链接:LINQ to SQL - 5 Minute Overview

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多