HttpWebRequest.Headers.Add("Cookie",value) vs Http

本文关键字:quot value vs Http Cookie Add Headers HttpWebRequest | 更新日期: 2023-09-27 18:32:38

当我得到HttpWebRequest的响应时,HttpWebRequest.Headers.Add("Cookie",value)HttpWebRequest.CookieContainer,结果是不同的。

那么,它们

之间有什么区别,以及何时使用它们。

HttpWebRequest.Headers.Add("Cookie",value) vs Http

根据我的经验,我在使用 HttpWebRequest.CookieContainer 管理 cookie 时遇到了一些问题。它可以在一定程度上工作,但有时 cookie 不符合 RFC 标准,并且它们无法正确解析到CookieContainer中。如果您通过将 Cookie 添加到请求中的 Cookie 标头来手动管理它们,则对于某些不符合 RFC 的网站,您将获得更好的成功。CookieContainer的问题之一是,如果日期中有一个带有逗号的日期,例如"2013 年 9 月 26 日",它会将其完全解析为单独的 cookie 并中断解析。另一个问题是HTTP 302重定向上设置的cookie不会被CookieContainer接收。

什么

最适合您的特定要求取决于您,但如果CookieContainer的问题提供的结果与手动设置 cookie 标头不同,我建议您坚持手动设置 cookie 标头。希望Microsoft将来会更新它,以便我们可以回到使用漂亮的 .NET 类来管理 cookie。

编辑:
我遇到了一些正确解析"Set-Cookie"标头的代码。它处理以逗号分隔的 Cookie,并提取每个 Cookie 的名称、过期时间、路径、值和域。

这段代码比Microsoft自己的cookie解析器更好用,这确实是官方cookie解析器应该做的。我不知道为什么Microsoft还没有解决这个问题,因为这是一个非常普遍的问题。

这是原始代码:http://snipplr.com/view/4427/

我在这里发布它,以防链接在某个时候关闭:

public static CookieCollection GetAllCookiesFromHeader(string strHeader, string strHost)
{
    ArrayList al = new ArrayList();
    CookieCollection cc = new CookieCollection();
    if (strHeader != string.Empty)
    {
        al = ConvertCookieHeaderToArrayList(strHeader);
        cc = ConvertCookieArraysToCookieCollection(al, strHost);
    }
    return cc;
}

private static ArrayList ConvertCookieHeaderToArrayList(string strCookHeader)
{
    strCookHeader = strCookHeader.Replace("'r", "");
    strCookHeader = strCookHeader.Replace("'n", "");
    string[] strCookTemp = strCookHeader.Split(',');
    ArrayList al = new ArrayList();
    int i = 0;
    int n = strCookTemp.Length;
    while (i < n)
    {
        if (strCookTemp[i].IndexOf("expires=", StringComparison.OrdinalIgnoreCase) > 0)
        {
            al.Add(strCookTemp[i] + "," + strCookTemp[i + 1]);
            i = i + 1;
        }
        else
        {
            al.Add(strCookTemp[i]);
        }
        i = i + 1;
    }
    return al;
}

private static CookieCollection ConvertCookieArraysToCookieCollection(ArrayList al, string strHost)
{
    CookieCollection cc = new CookieCollection();
    int alcount = al.Count;
    string strEachCook;
    string[] strEachCookParts;
    for (int i = 0; i < alcount; i++)
    {
        strEachCook = al[i].ToString();
        strEachCookParts = strEachCook.Split(';');
        int intEachCookPartsCount = strEachCookParts.Length;
        string strCNameAndCValue = string.Empty;
        string strPNameAndPValue = string.Empty;
        string strDNameAndDValue = string.Empty;
        string[] NameValuePairTemp;
        Cookie cookTemp = new Cookie();
        for (int j = 0; j < intEachCookPartsCount; j++)
        {
            if (j == 0)
            {
                strCNameAndCValue = strEachCookParts[j];
                if (strCNameAndCValue != string.Empty)
                {
                    int firstEqual = strCNameAndCValue.IndexOf("=");
                    string firstName = strCNameAndCValue.Substring(0, firstEqual);
                    string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1));
                    cookTemp.Name = firstName;
                    cookTemp.Value = allValue;
                }
                continue;
            }
            if (strEachCookParts[j].IndexOf("path", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                strPNameAndPValue = strEachCookParts[j];
                if (strPNameAndPValue != string.Empty)
                {
                    NameValuePairTemp = strPNameAndPValue.Split('=');
                    if (NameValuePairTemp[1] != string.Empty)
                    {
                        cookTemp.Path = NameValuePairTemp[1];
                    }
                    else
                    {
                        cookTemp.Path = "/";
                    }
                }
                continue;
            }
            if (strEachCookParts[j].IndexOf("domain", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                strPNameAndPValue = strEachCookParts[j];
                if (strPNameAndPValue != string.Empty)
                {
                    NameValuePairTemp = strPNameAndPValue.Split('=');
                    if (NameValuePairTemp[1] != string.Empty)
                    {
                        cookTemp.Domain = NameValuePairTemp[1];
                    }
                    else
                    {
                        cookTemp.Domain = strHost;
                    }
                }
                continue;
            }
        }
        if (cookTemp.Path == string.Empty)
        {
            cookTemp.Path = "/";
        }
        if (cookTemp.Domain == string.Empty)
        {
            cookTemp.Domain = strHost;
        }
        cc.Add(cookTemp);
    }
    return cc;
}