2013-09-25 36 views

Trả lời

7

Từ kinh nghiệm của tôi, tôi đã gặp phải một số vấn đề khi sử dụng HttpWebRequest.CookieContainer để quản lý cookie. Nó có thể hoạt động ở một mức độ, nhưng đôi khi các cookie không tuân thủ RFC và chúng không được phân tích cú pháp thành chính xác CookieContainer. Nếu bạn quản lý cookie của mình theo cách thủ công bằng cách thêm chúng vào tiêu đề Cookie theo yêu cầu, bạn sẽ có thành công tốt hơn với các trang web nhất định không tuân thủ RFC. Một trong những vấn đề với CookieContainer là nếu có ngày có dấu phẩy trong ngày, chẳng hạn như "ngày 26 tháng 9 năm 2013", nó sẽ phân tích cú pháp đó dưới dạng cookie riêng hoàn toàn và phá vỡ phân tích cú pháp. Một vấn đề khác là cookie được đặt trên chuyển hướng HTTP 302 sẽ không được chọn bởi số CookieContainer.

Tùy thuộc vào yêu cầu cụ thể của bạn, nhưng nếu các vấn đề với CookieContainer đang cung cấp kết quả khác với việc đặt tiêu đề cookie theo cách thủ công, tôi khuyên bạn nên đặt tiêu đề cookie theo cách thủ công. Hy vọng rằng Microsoft sẽ cập nhật điều này trong tương lai để chúng ta có thể quay lại sử dụng các lớp .NET tốt đẹp để quản lý các cookie.

Chỉnh sửa:
Tôi đã xem một số mã phân tích cú pháp tiêu đề "Đặt cookie" đúng cách. Nó xử lý các cookie được phân tách bằng dấu phẩy và trích xuất tên, hết hạn, đường dẫn, giá trị và tên miền của từng cookie.

Mã này hoạt động tốt hơn trình phân tích cú pháp cookie của Microsoft và đây thực sự là những gì mà trình phân tích cú pháp cookie chính thức cần thực hiện. Tôi không có bất kỳ đầu mối nào tại sao Microsoft chưa sửa lỗi này vì đây là một vấn đề rất phổ biến.

Đây là mã gốc: http://snipplr.com/view/4427/

tôi đăng nó ở đây trong trường hợp liên kết đi xuống tại một số điểm:

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; 
} 
Các vấn đề liên quan