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 にアクセスするにはどうすればよいですか? それらをすべて1つのコンテナに集めることはできますか?

ありがとう

4

2 に答える 2

8

この問題がオンラインで頻繁に発生することを考えると、問題は、.NET ライブラリ コードが複数の Set-Cookie ヘッダーをサポートしていないことだと思います (常に、または特定の状況下でのみ)。とにかく、回避するのはかなり簡単です。Set-Cookie ヘッダーから直接 Cookie を抽出するだけです。Set-Cookie ヘッダーから Cookie を直接抽出する方法を示すコード (このスレッドに添付されたコードからコピーされたもの) を次に示します。

    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 に答える