HttpWebRequest编程相关问题(2)

本文探讨了使用HttpWebRequest访问需要登录的页面时遇到的Cookies域匹配问题,并提供了一个较为完整的解决方案,确保所有相关Cookies都能正确传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在使用 HttpWebRequest访问需要登陆的页面时必然会涉及到Cookies,但是HttpWebRequest对象和相关方法在设计时还是存在一些问题

比如:

  1. 访问页面A,得到Cookie o1包含jspsessionid;
  2. 把o1给HttpWebRequest然后登陆页面B,得到一个新的Cookies o2,里面包含了很多相关信息;
  3. 把o2给HttpWebRequest然后登陆页面C.

一般情况下你会使用如下代码:

HttpWebRequest oRequest  =  (HttpWebRequest)HttpWebRequest.Create(oHead.Host +  oHead.Action);            
            oRequest.ProtocolVersion 
=   new  Version( " 1.1 " );
            oRequest.Referer 
=  oHead.Referer;
            oRequest.Accept 
=   " image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, */* " ;           
            oRequest.CookieContainer 
=   new  CookieContainer();
           oRequest.CookieContainer .Add(o2)
            oRequest.UserAgent 
=   " blogmove.cn " ;
            oRequest.Credentials 
=  CredentialCache.DefaultCredentials;

面的oRequest.CookieContainer.Add(o2)基本上没有错,而且按照道理来说也不会有错

但是事实上,Micosoft在设计这一部分是存在缺陷的,或者“Microsoft有独立的定位”,也许还有我不知道的地方

上文的代码一般情况下不会有错,Cookies值会被正常传递给服务器,但是如果o2的内容是下面的内容的话,上面的代码就可能会存在缺陷:

Set-Cookie: JSESSIONID=555287820C8B46311649EF947F77DF12; Path=/control
Set-Cookie: Code=b4874b74; Domain=blogmove.cn; Path=/
Set-Cookie: mc=1%2cplatform%2c0; Domain=blogmove.cn; Path=/
(注意这里是HttpHeader方式)

上面的这段Head假设是在访问http://file.blogmove.cn/t1.aspx  时,服务器写给浏览器的。

o2被传递给oRequest,oRequest访问http://file.blogmove.cn/test.aspx 时,上面三个cookie,只有第一个被oRequest传递给了服务器,服务器收不到后面两个cookies,Test.aspx页面就会返回错误的结果。

原因就是Cookie是有Domain的,

第一个Cookie的Domain是默认http://file.blogmove.cn;

第二和三个Cookie的Domain是blogmove.cn;

oRequest在上行Cookie时只上行了当前Domain=http://file.blogmove.cn的Cookie,而放弃了Domin=blogmove.cn的Cookie,oRequest分辨了Uri;

这种行为和我们正常预想的不符,因为我们平常是按照浏览器的行为在思考:应该上行所有blogmove.cn下的所有Cookies.

按照道理来说,我认为Request对象应该自动分辨和解析Cookies里面的domain.

因此为了保证oRequest能够达到我们的目的,所以应该修改上面的C#代码如下:

 

  public   string  Send( ref  SendHead oHead)
        
{
            HttpWebResponse oResponse
=null;
            HttpWebRequest oRequest 
= (HttpWebRequest)HttpWebRequest.Create(oHead.Host+ oHead.Action);            
            oRequest.ProtocolVersion 
= new Version("1.1");
            oRequest.Referer 
= oHead.Referer;
            oRequest.Accept 
= "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, */*";           
            oRequest.CookieContainer 
= new CookieContainer();            
            
if (oHead.Cookies != null)
            
{            
                
string cookiesValue = "";
                
foreach (Cookie o in oHead.Cookies)
                
{
                    cookiesValue 
+= o.Name+"="+ o.Value+",";
                }

                oRequest.CookieContainer.SetCookies(
new Uri(oHead.Host), cookiesValue);
            }

            
//oRequest.CookieContainer.SetCookies(oRequest.RequestUri,cookies[].
            oRequest.UserAgent = "NutsSoft.com.cn";
            oRequest.Credentials 
= CredentialCache.DefaultCredentials;

            
//设置POST数据
            if (oHead.Method.ToLower() == "post")
            
{
                oRequest.Method 
= "POST";
                
byte[] byteData = ASCIIEncoding.ASCII.GetBytes(oHead.PostData);
                oRequest.ContentType 
= "application/x-www-form-urlencoded";
                oRequest.ContentLength 
= byteData.Length;
                Stream WriteStream 
= oRequest.GetRequestStream();
                WriteStream.Write(byteData, 
0, byteData.Length);
                WriteStream.Close();
            }
            
            
try
            
{
                oResponse 
= (HttpWebResponse)oRequest.GetResponse();
            }

            
catch (WebException ex)
            
{
                oResponse 
= (HttpWebResponse)ex.Response;
            }

            oResponse.Cookies 
= oRequest.CookieContainer.GetCookies(oRequest.RequestUri);
            Stream dataStream 
= oResponse.GetResponseStream();

            
string en = oResponse.CharacterSet;
            
if (en == null) en = "gb2312";
            
if (en.ToLower() == "iso-8859-1") en = "gb2312";
            StreamReader reader 
= new StreamReader(dataStream, Encoding.GetEncoding(en));
            
string responseFromServer = reader.ReadToEnd();
            Cookies 
= oRequest.CookieContainer.GetCookies(oRequest.RequestUri);
            oHead.Cookies 
= oRequest.CookieContainer.GetCookies(oRequest.RequestUri); 
            reader.Close();
            dataStream.Close();
            oResponse.Close();
            
return oHead.Html=responseFromServer;
        }

这是一个相当完整的Send方法。不做过多的解释.

PS:这个Cookies上行问题耗费了一天时间来找出原因。

另:本文言语有点混乱。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值