基于HttpWebRequest的通用请求和响应处理

作者:小菜 更新时间:2025-02-19 点击数:
简介:使用HttpWebRequest和HttpWebResponse在后台进行文件的提交,可以替代使用前台form提交的方式,HttpWebRequest用来测试某

【菜科解读】

使用HttpWebRequest和HttpWebResponse在后台进行文件的提交,可以替代使用前台form提交的方式,HttpWebRequest用来测试某网页的速度是500多毫秒,而IE速度很快只有不到100毫秒,如何才能提高HttpWebRequest的响应速度?------解决方案--------------------------------------------------------看看服务器是否支持压缩,如果服务器支持压缩可能是因为IE接收的是压缩数据,你的程序时接收未压缩数据,所以比IE慢。

Httpwebrequest 的速度应该比IE快才对, 它不用渲染,HttpWebRequest是经过层层封装后得到的东西,IE应该是直接调用系统底层的方法,所以会比较快。

我使用过程中遇到的最大挑战是以下几个问题:a. 如何处理chunked的页面b. 如何处理gzip过的页面c. 如何自动判断文本编码d. 如何使用CookieContainer我们一个一个来,先从第一个开始。

chunked是常用的web服务器设置,也经常与gzip一起使用,

a. 如何处理chunked的页面

(fiddler的Response Header视图截图)

chunked的好处最主要的是页面优化,浏览器通常会在接收完第一个chunked块之后开始解析页面,而不是等到整个页面加载完成。

关于chunked的传输细节有兴趣的朋友可以继续阅读以下两篇文章http 《chunked传输》 《HTTP chunked+gzip及浏览器兼容测试》

由于页面的chunked,我们必须通过stream方式来获得数据,且由于之后要对获得的Stream进行gzip解密,所以我们需要把Stream暂时保存到MemoryStream中,如下所示:

MemoryStream memory = null; int length = 0; if (res.ContentLength > 0) { length = (int)res.ContentLength; } else{ length = 8000; } memory = new MemoryStream(length); Byte[] buf = new byte[4096]; Stream resStream = res.GetResponseStream(); int count = 0; do{ count = resStream.Read(buf, 0, buf.Length); if (count != 0) { memory.Write(buf, 0, count); } } while (count > 0);

这里利用ContentLength获取实际大小,但在有些情况下,ContentLength取不到,就会有个默认大小8000。

当然这只是MemoryStream初始,如果Write的时候超过,它会自动增加大小(我记得是默认大小的两倍)。

b. 如何处理gzip

gzip的好处想必不用我说了吧,自然是传输大小更小,动态压缩,目前大部分门户都会打开这个选项,其平均压缩效果可以达到不开之前的40%左右,以下是处理gzip的代码:

Stream responseStream = null; //handle gzip or deflate stream if (res.ContentEncoding.ToLower().Contains("gzip")) { responseStream = new GZipStream(memory, CompressionMode.Decompress); } else if (res.ContentEncoding.ToLower().Contains("deflate")) { responseStream = new DeflateStream(memory, CompressionMode.Decompress); } else{ responseStream = memory; }

压缩方式可以通过ContentEncoding属性获得,这里同时也处理了deflate的压缩方式,不过目前我没遇到过这种网站,这代码是拷贝过来的,呵呵。

c. 如何自动判断文本编码

编码问题往往是让人头疼的问题,因为某些情况你拿到的数据会变成乱码,这就表示编码没有处理好。

页面的实际编码是保存在ContentType中的,如下所示

(fiddler的Response Header视图截图)

这里的charset就是我们需要的编码信息,编码的自动选择全靠它了,编码的真正作用发生在我们把刚才的responseStream转换为string,代码如下所示:

int charsetPos = res.ContentType.IndexOf("charset="); string encoding = "UTF-8"; if (charsetPos >= 0) { int semicolonPos = res.ContentType.IndexOf(";", charsetPos); encoding = res.ContentType.Substring(charsetPos + 8, semicolonPos > 0 ? semicolonPos - charsetPos - 8 : res.ContentType.Length - charsetPos - 8); } var oEncoding = Encoding.GetEncoding(encoding); using (StreamReader sr = new StreamReader(responseStream, oEncoding)) { content = sr.ReadToEnd(); }

我这边用了比较原始的方法,没有用正则表达式,如果你觉得这个方法很挫,你可以换成正则表达式。

看到没,StreamReader通过oEncoding得知该用哪种编码来把byte[]转换为String。

(这里牵扯到几年前我做过的一道面试题:String和byte[]如何进行转换?说说你的经验。

这道题虽然很多公司不面,但我倒觉得这道题是可以深入的,因为encoding其实是个很不错的面试话题,也很考基础知识。

d. 如何使用CookieContainer

通常呢,稍微有点防御的网站都会验cookie,或者放个身份认证的cookie,如何在请求中放cookie呢,自然是靠CookieContainer(其实也可以通过AddHttpHeader,但本文只讨论CookieContainer,好处等会儿说,先卖个关子。

)CookieContainer的接口有点搞,因为既有Add,也有SetCookie,我一开始就上了老当,用了Add,结果没有效果。

SetCookies才是正确的方法,这个方法即可以一次性设置完所有的cookie,也可以一个一个设置,如下:

CookieContainer cookieContainer = new CookieContainer(); cookieContainer.SetCookies(new Uri(hostname), new Cookie("aaa", "98d4c408-7923-443a-ba3f-99df3bea7792", "/", "a.com").ToString()); cookieContainer.SetCookies(new Uri(hostname), new Cookie("bbb", "0", "/", "a.com").ToString()); cookieContainer.SetCookies(new Uri(hostname), new Cookie("ccc", "0", "/", "a.com").ToString()); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); req.AllowAutoRedirect = true; req.Accept = "text/html, application/xhtml+xml, */*"; req.Timeout = 50000; req.Method = "GET"; req.CookieContainer = cookieContainer; var response = (HttpWebResponse)req.GetResponse();

这里使用Cookie而非直接用字符串是出于安全考虑,因为Cookie对象的ToString自动帮我们把encoding做掉了,所以这么写会比直接用字符串来的安全,SetCookies是需要指定Url的,不过通常对于同一个网站host应该是一样的,比如www.a.com,不过目前还没遇到过跨域问题,等遇到了我单独写一篇讨论,跨域可又是另外一个头疼的问题了。

这里要说一下CookieContainer和AddHttpHeader的区别,首先这两个不能同时使用,只能用一个,其次CookieContainer毕竟是容器,所以理论上可以把另外一个请求的cookie一起带过来,然后实现cookie传递逻辑,而AddHttpHeader做不到这一点,这是最大的区别。

先写到这,大家有什么关于HttpWebRequest的其他心得可以发在回复中,我会整理后更新这个帖子。

基于,HttpWebRequest,的,通用,请,求和,响应

燕窝炖完一丝一丝的好还是粘粘的好

燕窝是生活中比较常见的一种滋补食品,它具有很不错的功效与作用,适量食用可以起到美容颜养颜的功效,深受人们喜欢。

燕窝一般都是炖着吃的,炖好的燕窝大多都是一丝一丝的,这个是正常的,可以放心食用。

燕窝炖完一丝一丝的好还是粘粘的好一般都是一丝丝的。

炖后燕窝呈丝状是正常的,这也是燕窝质量好的最好证明。

炖燕窝的真相是燕窝本身有天然的线条,我们在浸泡头发时会把燕窝撕成燕子条。

所以炖菜看起来像丝绸。

当燕窝不是一丝炖的时候,这个时候不要轻易吃燕窝,因为燕窝不是一丝炖的,很可能是假的燕窝。

假燕窝添加了胶体,质地不自然。

燕窝是炖的,不能与水融合,也不能用筷子捡起来。

如果鸟巢是用猪皮和其他材料做成的,那么鸟巢就不是条形的。

如果燕窝上涂了胶水,炖燕窝时就没有变化。

炖燕窝时,消费者可以放心食用。

燕窝炖出来一丝一丝的怎么办这个是正常现象,可以放心食用。

一般来说,整个燕窝煮熟后,会一个接一个地变湿,比干燥时膨胀得多。

血燕的扩张不如白燕明显。

白燕子会变得越来越滑,而白燕子会变得越来越滑。

相比之下,血燕则需要清晰的轮廓,并在嘴里咀嚼。

一般来说,炖燕窝是半透明的,散发出淡淡的蛋清味道。

它与水结合在一起,可以用筷子捡起来。

好的炖燕窝是顺滑的,而差的炖燕窝是与水不相容的,或者有太多的杂质和异味。

在常温水中浸泡4-6小时后,真正的干燕窝看起来晶莹剔透,呈丝带状,具有一定的软弹性。

煮沸后,它尝起来像液体果冻,有强烈的蛋清味道。

它很快就会在你嘴里融化。

炖燕窝的技巧1.浸泡时间由于燕窝类型和采摘时间的不同,毛发浸泡时间也有巨大差异。

例如,浸泡头发只需要2个小时,但管燕浸泡头发需要4-8个小时。

此外,雨季采摘的鸟巢含有一定的水分,因此比其他季节采摘的鸟巢更快。

因此,在购买燕窝时,必须询问燕窝的品种和采摘季节,并灵活调整浸泡时间。

2.炖煮时间当燕窝完全浸泡后,燕窝一般会炖30分钟左右。

然而,例如,在雨季采摘的鸟巢和稀疏的灯具只需要炖大约20分钟。

这里还有一个总结。

燕子越厚,头发浸泡时间和炖煮时间越长。

相反,这需要更短的时间。

3.火候用于炖燕窝的炖杯,大部分由玻璃和陶瓷制成,是电炖锅。

你只需要加入原料并设定时间。

热量经过智能调节。

但如果我们用炉子炖,我们可以按照以下步骤加热:用高火煮至沸腾,等待三分钟,关小火,继续炖20分钟左右。

用这种方法炖的燕窝味道更好,不容易融化。

4.配料入锅时间对于这个问题,我们应该根据不同的成分进行区分。

最常见的燕窝配方是牛奶燕窝和冰糖燕窝。

这两种食材可以直接食用,所以可以在出锅前五分钟放入。

同样的配料包括红枣、龙眼等。

莲子、燕窝等食材也需要煮熟食用。

配料应与燕窝一起放入锅中。

同样适用的成分包括百合、木瓜等。

燕窝炖好后是粘稠液体还是水水的

燕窝是生活中比较常见的一种滋补食物,它吃起来味道很不错,营养价值高,很多人都会自己在家炖燕窝吃。

炖燕窝也会有一定的讲究和技巧,通常炖好之后的燕窝不是脆的,它的质地和果冻有点像,吃起来软软的,q弹可口,有点粘稠。

燕窝炖好后是粘稠液体还是水水的燕窝炖出来是有可能是水水的,也有可能是稠稠的。

燕窝,没有经过药物加工漂白或其蛋白质结构被改变过的洞燕或屋燕炖煮时水温达到80时就会加速燕窝溶化。

燕窝是水溶性蛋白质,一般浸泡发好的燕窝入锅炖煮水沸腾计时30分钟左右就开始溶化,所以要吃有口感的燕窝就炖煮30分钟左右。

燕窝炖化了会影响燕窝的口感和营养,炖煮时要注意燕窝的炖煮时间。

燕窝炖出来可能是水水的,也可能是稠稠的。

燕窝炖成什么样才算好不同种类的燕窝的炖煮时间上会存在一定的差异,一般白燕盏的最佳炖煮时长在30分钟至40分钟之间,血燕盏的最佳炖煮最佳时间在50分钟至60分钟之间,但炖煮燕窝的时长只能当作判断燕窝是否炖熟的次要因素,如果想要判断燕窝是否炖煮好了,重要从燕窝的形态、香味、色泽这三个重要因素来看。

不同种类的燕窝炖制时间会有所不同。

一般来说,白燕窝的最佳炖制时间为30-40分钟,血燕窝的最佳炖制时间为50-60分钟。

然而,燕窝的炖制时间只能当作判断燕窝是否炖制的次要因素。

如果要判断燕窝是否炖,重要从燕窝的形状、香气和颜色三个重要因素来判断。

1.看形态炖燕窝将与水融为一体,燕子丝将沉入炖杯底部,这是完全透明的,有点像果冻的形状。

没有炖菜的燕窝是白色半透明的,看起来很透明,没有弹性。

炖燕窝是完全透明的,口感柔软,没有坚硬的心。

2.看味道燕窝重要由水溶性蛋白质组成。

好的燕窝炖熟后,会有类似蛋清的味道,腥味会减弱,变得不那么明显。

没有炖过的燕窝不会出现在蛋清的味道里。

3.看口感炖燕窝口感柔软糯滑,丝滑爽口,像吃果冻一样,但不炖燕窝会有点脆甚至硬。

味道和扇子一样,没有炖,中间会有一颗坚硬的心。

好的燕窝炖菜色泽透明,口感顺滑。

它没有油腻感,味道芳香。

捡起燕子丝后,碗里只剩下一点点水。

在大多数情况下,白眼中可能含有纯净水1;40,用小火炖30-40分钟,燕窝就会炖熟。

炖燕窝的技巧1.浸泡时间:一般情况下,鸟巢可以完全浸泡2小时。

不要整晚泡它。

浸泡了很长时间的燕窝极不耐炖。

炖20分钟后可能会变成水。

2.水量:如果排水太少,鸟巢会变硬;燕窝水平面以上2-5cm最适中,味道最好;如果水量超过5厘米,很容易融化水。

3.炖具:在炉子里炖菜时要注意温度,一般20-25分钟。

如果时间太长,水很容易融化;电饭煲的炖菜很香,一般30-40分钟;全智能全自动炖燕窝锅,炖燕窝20分钟,易长时间融化水分。

以上都是指在水中炖。

4.燕窝本身的厚度:较厚的燕窝,如老燕子、黄燕子、石窟燕子,更耐炖,而雨季新鲜燕窝只需炖20-30分钟,炖久后容易翻水。

炖燕窝需要掌握正确的炖燕窝方法。

在纯化水中浸泡1-2小时。

不要用太多的水覆盖鸟巢。

用手轻轻撕下难以浸湿头发的部位,如燕角。

用泡沫冲洗燕窝,挑出细小的绒毛和杂质。

将其放入炖杯中,加入纯水覆盖一两个燕窝手指,在水中炖30分钟。

炖燕窝的温度最好控制在80度左右。

加入收藏
               

基于HttpWebRequest的通用请求和响应处理

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录