【问题】
模拟登陆:
(用户名:72qt
密码:hx123456)
对应的核心部分是:
然后用代码:
public void emualeLoginAndAdd() { crifanLib crl = new crifanLib(); Dictionary<string, string> headerDict; Dictionary<string, string> postDict; //step1: http://new.guguyu.com/add.php string addPhpUrl = "http://new.guguyu.com/add.php"; headerDict = new Dictionary<string, string>(); headerDict.Add("Referer", addPhpUrl); headerDict.Add("DNT", "1"); headerDict.Add("Accept-Language", "zh-CN"); string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK"); //step2: http://new.guguyu.com/add.php?nk=1 headerDict = new Dictionary<string, string>(); headerDict.Add("Referer", addPhpUrl); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); headerDict.Add("DNT", "1"); headerDict.Add("Accept-Language", "zh-CN"); postDict = new Dictionary<string, string>(); //uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21 postDict.Add("uname", txtUserName.Text); postDict.Add("pwd", txtPassword.Text); postDict.Add("Submit.x", "44"); postDict.Add("Submit.y", "21"); string addNk1Url = "http://new.guguyu.com/add.php?nk=1"; string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script> //step3: http://new.guguyu.com/add/ string addUrl = "http://new.guguyu.com/add/"; headerDict = new Dictionary<string, string>(); headerDict.Add("Referer", addNk1Url); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); headerDict.Add("DNT", "1"); headerDict.Add("allowautoredirect", "false"); headerDict.Add("Accept-Language", "zh-CN"); string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html //step4: http://new.guguyu.com/add/?nk=1 string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1"; headerDict = new Dictionary<string, string>(); headerDict.Add("Referer", addUrl); headerDict.Add("allowautoredirect", "false"); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); headerDict.Add("DNT", "1"); headerDict.Add("Accept-Language", "zh-CN"); string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK"); }
去调试,结果始终后面的结果不对:
step3去访问:
但是得到的,不是正常的html,而是之前的那个:
<script>location.href='/add/'</script>
对应的,step4,获得也不是正常的html,也是上面的那个值。
【解决过程】
1.调试了N个小时,最终找到根本原因了:
C#代码:
resp = (HttpWebResponse)req.GetResponse(); updateLocalCookies(resp.Cookies, ref curCookies);
中的resp.Cookies,其实是
C#的http库,针对:
{Vary: Accept-Encoding Content-Length: 53 Content-Type: text/html Date: Thu, 01 Aug 2013 16:05:12 GMT Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT Server: Apache/2.2.9 (APMServ) PHP/5.2.6 X-Powered-By: PHP/5.2.6 } |
中的:
Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT |
解析后的cookie,但是,由于C#的解析Set-Cookie有bug,导致解析出来的cookie,虽然其他值都对,包括name是UNAME,但是path的值却出错了:
path="add.php" |
而实际上,应该是:
path="" |
对应的,抓包出来的是正常的,path是空的:
2.知道原因后,结果就可以去修改代码了:
主要就是:
要么手动去把cookie的path值清空;
要么去删除错误的cookie,重新自己写代码解析Set-Cookie,以此获得正确的path为空的cookie;
此处用后者,代码为:
public void emualeLoginAndAdd() { crifanLib crl = new crifanLib(); Dictionary<string, string> headerDict; Dictionary<string, string> postDict; //step1: http://new.guguyu.com/add.php string addPhpUrl = "http://new.guguyu.com/add.php"; headerDict = new Dictionary<string, string>(); headerDict.Add("Referer", addPhpUrl); headerDict.Add("DNT", "1"); headerDict.Add("Accept-Language", "zh-CN"); string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK"); //step2: http://new.guguyu.com/add.php?nk=1 headerDict = new Dictionary<string, string>(); headerDict.Add("Referer", addPhpUrl); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); headerDict.Add("DNT", "1"); headerDict.Add("Accept-Language", "zh-CN"); postDict = new Dictionary<string, string>(); //uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21 postDict.Add("uname", txtUserName.Text); postDict.Add("pwd", txtPassword.Text); postDict.Add("Submit.x", "44"); postDict.Add("Submit.y", "21"); string addNk1Url = "http://new.guguyu.com/add.php?nk=1"; //string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script> //!!! here, above step, will got a uncorrect cookie //which abnormally, pass: //Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT //into cookie name is "UNAME",but path="/add" -> correct one should be path="" //so following, use manually process cookie HttpWebResponse addNk1Response = crl.getUrlResponse(addNk1Url, headerDict: headerDict, postDict: postDict);//<script>location.href='/add/'</script> String curDomain = crl.extractHost(addPhpUrl);//new.guguyu.com CookieCollection parsedCookies = crl.parseSetCookie(addNk1Response.Headers["Set-Cookie"], curDomain); CookieCollection curCookies = crl.getCurCookies(); crl.updateLocalCookies(parsedCookies, ref curCookies); crl.setCurCookies(curCookies); //step3: http://new.guguyu.com/add/ string addUrl = "http://new.guguyu.com/add/"; headerDict = new Dictionary<string, string>(); headerDict.Add("Referer", addNk1Url); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); headerDict.Add("DNT", "1"); headerDict.Add("allowautoredirect", "false"); headerDict.Add("Accept-Language", "zh-CN"); string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html //step4: http://new.guguyu.com/add/?nk=1 string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1"; headerDict = new Dictionary<string, string>(); headerDict.Add("Referer", addUrl); headerDict.Add("allowautoredirect", "false"); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); headerDict.Add("DNT", "1"); headerDict.Add("Accept-Language", "zh-CN"); string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK"); // here can get real html, which conains /* <td colspan='2' align='center'> <input style='height: 25px;' name='submit' type='submit' id='submit' value=' 提 交 ' onClick='return Ck();'/> <input name='check' type='hidden' value='6283' /> <a href='javascript:;' onClick="faka('kadd');"><font color='red' size='3'>【附加新手卡】</font></a> <a href='?nk=5'><font size='3'>【批量发布新服】</font></a> 全部发完后请到<a href='?nk=10'>管理新服</a>检查一下,确保无误!</td> */ }
解析后的cookie,path是空的:
3.经过继续的验证,发现很多参数,是可以去掉的:
public void emualeLoginAndAdd() { crifanLib crl = new crifanLib(); Dictionary<string, string> headerDict; Dictionary<string, string> postDict; //step1: http://new.guguyu.com/add.php string addPhpUrl = "http://new.guguyu.com/add.php"; headerDict = new Dictionary<string, string>(); //headerDict.Add("Referer", addPhpUrl); //headerDict.Add("DNT", "1"); //headerDict.Add("Accept-Language", "zh-CN"); string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK"); //step2: http://new.guguyu.com/add.php?nk=1 headerDict = new Dictionary<string, string>(); //headerDict.Add("Referer", addPhpUrl); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); //headerDict.Add("DNT", "1"); //headerDict.Add("Accept-Language", "zh-CN"); postDict = new Dictionary<string, string>(); //uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21 postDict.Add("uname", txtUserName.Text); postDict.Add("pwd", txtPassword.Text); //postDict.Add("Submit.x", "44"); //postDict.Add("Submit.y", "21"); string addNk1Url = "http://new.guguyu.com/add.php?nk=1"; //string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script> //!!! here, above step, will got a uncorrect cookie //which abnormally, pass: //Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT //into cookie name is "UNAME",but path="/add" -> correct one should be path="" //so following, use manually process cookie HttpWebResponse addNk1Response = crl.getUrlResponse(addNk1Url, headerDict: headerDict, postDict: postDict);//<script>location.href='/add/'</script> String curDomain = crl.extractHost(addPhpUrl);//new.guguyu.com CookieCollection parsedCookies = crl.parseSetCookie(addNk1Response.Headers["Set-Cookie"], curDomain); CookieCollection curCookies = crl.getCurCookies(); crl.updateLocalCookies(parsedCookies, ref curCookies); crl.setCurCookies(curCookies); //step3: http://new.guguyu.com/add/ string addUrl = "http://new.guguyu.com/add/"; headerDict = new Dictionary<string, string>(); //headerDict.Add("Referer", addNk1Url); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); //headerDict.Add("DNT", "1"); //headerDict.Add("allowautoredirect", "false"); //headerDict.Add("Accept-Language", "zh-CN"); string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html //step4: http://new.guguyu.com/add/?nk=1 string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1"; headerDict = new Dictionary<string, string>(); //headerDict.Add("Referer", addUrl); //headerDict.Add("allowautoredirect", "false"); //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); //headerDict.Add("DNT", "1"); //headerDict.Add("Accept-Language", "zh-CN"); string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK"); // here can get real html, which conains /* <td colspan='2' align='center'> <input style='height: 25px;' name='submit' type='submit' id='submit' value=' 提 交 ' onClick='return Ck();'/> <input name='check' type='hidden' value='6283' /> <a href='javascript:;' onClick="faka('kadd');"><font color='red' size='3'>【附加新手卡】</font></a> <a href='?nk=5'><font size='3'>【批量发布新服】</font></a> 全部发完后请到<a href='?nk=10'>管理新服</a>检查一下,确保无误!</td> */ }
4.其中,用到的crifanLib.cs,详见:
http://code.google.com/p/crifanlib/source/browse/trunk/csharp/crifanLib.cs
【总结】
加上之前遇到的一个bug:
【已解决】C#中得到的Http的response中的Set-Cookie的内容的格式不对/错误/不正确 –> 已实现把Set-Cookie部分的字符串解析为CookieCollection
【经验记录】C#中,库函数有bug,会将http所返回的response响应中的headers头信息中的Set-Cookie值,解析错误,丢失部分cookie
算下来,C#的http的库,在解析cookie方面(解析返回的Set-Cookie)方面,真的是,bug奇多,害人不浅啊。
转载请注明:在路上 » 【已解决】又发现一个C#中解析Set-Cookie的一个bug:无故地添加cookie的path域