昨天在爬数据时,发现某个网站Response.Get过来的数据一直是为空。当时就很奇怪,认真看下了响应头。发现Transfer-Encoding:chunked这个玩意
网上查了下资料
一般情况HTTP的Header包含Content-Length域来指明报文体的长度。
有时候服务生成HTTP回应是无法确定消息大小的,比如大文件的下载,或者后台需要复杂的逻辑才能全部处理页面的请求,这时用需要实时生成消息长度,服务器一般使用chunked编码。
在进行Chunked编码传输时,在回复消息的Headers有transfer-encoding域值为chunked,表示将用chunked编码传输内容。使用chunked编码的Headers如下(可以利用FireFox的FireBug插件或HttpWatch查看Headers信息,HttpWatch还可以查看chunked的个数):
编码使用若干个Chunk组成,由一个标明长度为0的chunk结束,每个Chunk有两部分组成,第一部分是该Chunk的长度和长度单位(一般不写),第二部分就是指定长度的内容,每个部分用CRLF(全称carriage return/line feed 回车换行)隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些没有写的头部内容。
这上面是网上的原话,具体更详细的可以去参考里面看看
不过网上很多关于chunked .net解析都是tmd无用,把代码贴出来,后面的小哥们不要再痛苦。
哥当时也是写不出解析代码,想着网上找找,国内找的都千扁一屡,最后在国外论坛找到了方案。
最后通过Fiddler调试看到,POST的网站有返回Content-Length,此时心都炸了。找了半天,你居然告诉我,是有Length返回。但是浏览器F12看到的却是Transfer-Encoding:chunked。
试着在Fiddler上面模拟调试,看看请求前,请求后的变化。
把浏览器请求头内容复制到Fiddler的参数里面,点击exec,响应区域显示为空。我的神哟这tmd什么情况,参数有问题?,认真对照一下吧,总会发现有问题
。。。。。
当时我没有特别注意Cookie,也没有传过去,Cookie为空。把浏览器里面的Cookie信息拷贝进去。exec,断点命中了。。。。。。。。。当时是多么的开心,说明这个网站的POST必须要cookie
解析代码也找到,那再把.net代码检查下。运行,拿到了数据。。。。不写了
贴代码
StringBuilder sb1 = new StringBuilder(); Byte[] buf = new byte[256]; Stream resStream = myHttpWebResponse.GetResponseStream(); resStream = new GZipStream(resStream, CompressionMode.Decompress); string tmpString = null; int count = 0; do { count = resStream.Read(buf, 0, buf.Length - 1); if (count != 0) { tmpString = Encoding.UTF8.GetString(buf, 0, count); sb1.Append(tmpString); } } while (count > 0);
参考
https://imququ.com/post/transfer-encoding-header-in-http.html
还有一个网站找不到了,可怜了。
http://www.dayuji1000.com/vrtechnews/index.html
http://www.xafuda.cn/article/jnd3.5.html