我正在使用HttpWebRequest
和HttpWebResponse
来抓取网站。我为每个请求使用相同的CookieContainer
,确保自动处理cookie。
但是,其中一个请求需要一个特定的cookie,该cookie在之前的响应中设置。虽然它存在于集合中,但其Path
属性显示不正确。根据{{3}}(页7),当使用空白路径设置cookie时(如此),应将路径设置为请求的URL,但不包括最终斜杠。实际发生的是它被设置为整个 URL路径,这意味着cookie不能随后被同一子域中的不同URL读取。
一个例子:
Set-Cookie
标题,其中包含 mycookie = 12345;
expires = Wed,27-Jun-2012 16:20:00 GMT 我使用带有Firebug和Firecookie扩展的Firefox浏览器执行了相同的导航步骤。路径设置正确,即在真实浏览器会话中设置为子域。
任何人都可以确认这一点并可能指出我的解决方法或解决此问题吗?非常感谢。
答案 0 :(得分:3)
以下是有问题的内部代码。看起来不像是一个意外的错误。如果不符合标准,您应该报告问题。
switch (this.m_cookieVariant)
{
case CookieVariant.Plain:
this.m_path = absolutePath;
break;
case CookieVariant.Rfc2109:
this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/'));
break;
default:
this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/') + 1);
break;
}
因此它使用Plain cookie变体,除非在cookie本身另有说明。
您将不得不迭代所有Cookie检查。真的,这是我讨厌.net的cookie处理的众多原因中的一个。无法轻松获取所有域名/ Cookie。最简单的解决方法是执行以下操作。但是,您最终会得到重复的Cookie。所以你可能想要通过uri获取cookie。
public static CookieCollection FixCookies(CookieCollection collection)
{
foreach (Cookie cookie in collection)
{
if (string.IsNullOrEmpty(cookie.Path))
continue;
int idx = cookie.Path.LastIndexOf('/');
if (idx == -1)
continue;
cookie.Path = cookie.Path.Substring(0, idx);
}
return collection;
}
[STAThread]
private static void Main(string[] args)
{
var http = (HttpWebRequest)WebRequest.Create("http://localhost/test/test.php");
http.CookieContainer = new CookieContainer();
var resp = (HttpWebResponse)http.GetResponse();
http.CookieContainer.Add(FixCookies(resp.Cookies));
}