今天遇到个问题,一个网站登录请求返回的HttpResult的Cookie字符串不为空,CookieCollection的Count却为0。返回的Cookie字符串是这样:
[SQL] 纯文本查看 复制代码 JSESSIONID=EB3A9A7D49A4AB4C44D7838821CC8D48; Secure; HttpOnly; Expires=07-08-2019 13:16:01,
_tf_sso_main_session_id=EB3A9A7D49A4AB4C44D7838821CC8D48; Domain=aaa.cn; Path=/; HttpOnly
返回了2个cookie,第一个cookie却没有Domain设置,经过测试后发现,HttpWebResponse response在解析cookie的时候,如果这个cookie没有设置Domian,就会引发异常,导致这个以后的所有cookie都不会被解析进response.cookies中,这是导致这个问题的原因。
知道了原因,处理办法就很简单了,如果发现Cookie字符串不为空,CookieCollection的Count为0的情况,就手动解析Cookie字符串,把没有Domian的cookie手动加上当前访问的Host,然后把Cookie加入手动创建CookieCollection中,代码如下:
HTTP访问处理:
[C#] 纯文本查看 复制代码 HttpResult ret = m_hb.GetHtml(itm);
if (ret.Cookie.Split(',').Length > ret.CookieCollection.Count)
{
string host = ret.Header["Host"];
if (null == host || host.Length == 0)
{
Uri uri = new Uri(itm.URL);
host = uri.Host;
}
CookieCollection cookielist = BaseTool.StrCookieToCookieCollection(host, ret.Cookie);
cookie.Add(cookielist);
}
else
{
cookie.Add(ret.CookieCollection);
}
StrCookieToCookieCollection实现:
[C#] 纯文本查看 复制代码 public CookieCollection StrCookieToCookieCollection(string baseDomain, string cookiestr)
{
CookieCollection cc = new CookieCollection();
string[] cookies = cookiestr.Split(',');
foreach(string c in cookies)
{
Cookie cookie = new Cookie();
string[] list = c.ToString().Split(new string[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string item in list)
{
string itemcookie = item.ToLower().Trim().Replace("\r\n", string.Empty).Replace("\n", string.Empty);
//排除空字符串
if (string.IsNullOrWhiteSpace(itemcookie)) continue;
else if (!itemcookie.Contains("="))
{
if(itemcookie == "httponly")
cookie.HttpOnly = true;
else if(itemcookie == "secure")
cookie.Secure = true;
}
else if (itemcookie.Contains("path="))
{
cookie.Path = itemcookie.Replace("path=", string.Empty);
}
else if (itemcookie.Contains("expires="))
{
cookie.Expires = Convert.ToDateTime(itemcookie.Replace("expires=", string.Empty));
}
else if (itemcookie.Contains("domain="))
{
cookie.Domain = itemcookie.Replace("domain=", string.Empty);
}
else
{
string[] kv = item.ToString().Replace("\r\n", string.Empty).Replace("\n", string.Empty).Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
if (kv.Length == 2)
{
cookie.Name = kv[0].Trim();
cookie.Value = kv[1].Trim();
}
}
}
if (cookie.Domain.Length == 0)
{
cookie.Domain = baseDomain;
}
cc.Add(cookie);
}
return cc;
}
这么处理,就解决了没有Domian的Cookie不能被记录的问题。
|