工作需要,最近捣鼓了一阵子HttpWebRequest。感觉用的云里雾里的。
在使用Get的时候,用法比较简单,拼接好url即可。可是用POST的时候,老是出问题,认证一直失败。而且一个请求会分两次发送两个http包。所以配合抓包工具,仔细研究了一下它的工作流程。
HttpWebRequest类的msdn link如下http://msdn.microsoft.com/zh-cn/library/system.net.httpwebrequest_members(v=vs.80).aspx
先把理顺的总结一下:
1. 不要使用HttpWebRequest的构造函数,使用WebRequest.Create(url)创建实例时,如果url的协议为“http://...” 或者 "https://...",将自动返回HttpWebRequest对象。
2. 当Method 为‘GET’ 时,HttpWebRequest相对比较好用,拼接好url地址即可,需要注意的是默认HttpWebRequest不支持cookie,如果需要,可以设置Cookiecontainer,因为没有用到,所以也不甚明了。
3. 当Method为'POST'时,HTTP请求并不是调用HttpWebRequest.GetResponse()时才发起的!因此会一个POST请求会分成两份,一份是head,设置的HttpWebRequest的header信息等都会封装在第一个包里面,当调用request.GetRequest.Stream()时,会发送第一个HTTP包,把包头内容发送给url,得到一个http response,该包的状态信息为Status:Continue,此时向HttpWebRequest的GetRequestStream()里面写数据,则会用写入的数据发送第二个http包,内容只有一个,就是POST的参数信息。
HttpWebRequest.GetRequestStream()时:
想获取的Stream写入数据时:
Http Payload包里的内容:
在PHP的curl库里面,http的request可以放在一个包里面,而不需要像这样来回问答的方式发送数据,可惜我还没找到什么好的方法。望前辈大侠们不吝赐教
==================================================================================
搞定问题了,最近查了查HTTP的书,发现这个是http协议里面允许的情况,目的就是为了客户端发送一大堆无用的body到错误的server,造成网络资源的浪费。所以先发送一个header的包,询问服务器是否是你可以接受的。
等待服务器返回个100 continue的应答之后,再把包含内容的body发送过去。而且HttpWebRequest也可以指定是否这么工作。默认值应该是true:
1 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 2 request.Headers.Clear(); 3 4 // set Expect100Continue to false, so it will send only one http package. 5 request.ServicePoint.Expect100Continue = false;
request.ServicePoint.Expect100Continue = false;
设置了service point的这个属性之后。request就会把请求的body和header一起发送出去了。具体用哪种,可以根据需要而定。body包很小就可以直接发送出去。如果发送的内容比较大,就可以先询问一下server后发送。避免浪费网络资源。
Thanks