4

如何处理具有“/”以外路径的 cookie。HttpWebRequest 对象返回以下标头:

HTTP/1.1 302 Moved Temporarily
Transfer-Encoding: chunked
Date: Wed, 10 Jun 2009 13:22:53 GMT
Content-Type: text/html; charset=UTF-8
Expires: Wed, 10 Jun 2009 13:22:53 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Server: nginx/0.7.41
X-Powered-By: PHP/5.2.9
Last-Modified: Wed, 10 Jun 2009 13:22:52 GMT
Pragma: no-cache
Set-Cookie: cookie1=c1; path=/; domain=site.com
Set-Cookie: cookie2=c2; path=/content; domain=site.com; httponly
Set-Cookie: cookie3=c3; path=/admin; domain=site.com; httponly
Set-Cookie: cookie4=c4; path=/; domain=site.com; httponly
Location: http://site.com/admin/
Via: 1.1 mvo-netcache-02 (NetCache NetApp/6.0.7)

遍历 cookie 集合仅包含路径为“/”的 cookie。所以cookiecontainer里面只有cookie1和cookie4。

为什么其余的不被收集?如何使用“/”以外的路径访问 cookie?我可以将它们全部收集在一个容器中吗?

谢谢

4

2 回答 2

8

Given how frequently this issue comes up online, I suspect the problem is that the .NET library code doesn't support multiple Set-Cookie headers (either all the time or only under some circumstances). Regardless, it's pretty easy to work around. Just extract the cookies directly from the Set-Cookie headers. Here's some code (originally copied from code attached to this thread) which shows how to extract cookies directly from the Set-Cookie header.

    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;
    }
于 2009-09-22T20:12:34.440 回答
4

实际上 CookieContainer 得到了所有的 cookie,但你看不到它们。当您从 GelCookies() 方法中获取它时,它会根据当前路径和域为您提供合适的 cookie。

CookieContainer 将处理域、路径以及到期,但它在子域处理中存在错误。

检查此以获取详细信息和错误修复: http ://dot-net-expertise.blogspot.com/2009/10/cookiecontainer-domain-handling-bug-fix.html

于 2009-10-08T13:09:10.910 回答