国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

httpclient訪問(wèn)網(wǎng)站時(shí)設(shè)置Accept-Encoding為gzip,deflate返回的結(jié)果為亂碼的問(wèn)題

2019-11-15 00:32:36
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
httpclient訪問(wèn)網(wǎng)站時(shí)設(shè)置Accept-Encoding為gzip,deflate返回的結(jié)果為亂碼的問(wèn)題

近期迷戀上httpclient模擬各種網(wǎng)站登陸,瀏覽器中的開(kāi)發(fā)者工具中查看請(qǐng)求頭信息,然后照葫蘆畫(huà)瓢寫(xiě)到httpclient的請(qǐng)求中去,requestheader中有這么一段設(shè)置:

Accept-Encoding      gzip,deflate

之前模擬其他網(wǎng)站的時(shí)候這塊并沒(méi)有太在意,因?yàn)闊o(wú)論我在httpclient中添加上這段還是不添加,請(qǐng)求網(wǎng)站數(shù)據(jù)都沒(méi)有任何影響,也不影響網(wǎng)站的安全檢測(cè),所以當(dāng)時(shí)也就沒(méi)有特別關(guān)注這個(gè)設(shè)置,直到模擬登陸58同城網(wǎng)站的時(shí)候第一次遇到這個(gè)問(wèn)題,當(dāng)添加上以上的這行請(qǐng)求頭設(shè)置的時(shí)候,返回的網(wǎng)頁(yè)數(shù)據(jù)是亂碼,而且是那種各種粗體方塊的亂碼,經(jīng)驗(yàn)告訴我這種亂碼表現(xiàn)并不是簡(jiǎn)單的編碼錯(cuò)誤造成的,因?yàn)橹辽儆⑽牟粦?yīng)該出現(xiàn)亂碼..而且如果是簡(jiǎn)單的gbk,utf-8之間的亂碼也不會(huì)出現(xiàn)這種大面積的粗體方塊..

然后想到這個(gè)Accept-Encoding,百度后知道,這個(gè)是用來(lái)設(shè)置從網(wǎng)站中接收的返回?cái)?shù)據(jù)是否進(jìn)行g(shù)zip壓縮.這也就解釋了為何返回的數(shù)據(jù)是大面積的粗體方塊亂碼,因?yàn)槭菈嚎s過(guò)的數(shù)據(jù),也就不可能進(jìn)行正常解碼.

http://blog.csdn.net/zhangxinrun/article/details/5711307 這是一篇介紹gzip,deflate具體含義的博文

防止鏈接失效我直接摘抄一段:

gzip是一種數(shù)據(jù)格式,默認(rèn)且目前僅使用deflate算法壓縮data部分;deflate是一種壓縮算法,是huffman編碼的一種加強(qiáng)。deflate與gzip解壓的代碼幾乎相同,可以合成一塊代碼。區(qū)別僅有:deflate使用inflateInit(),而gzip使用inflateInit2()進(jìn)行初始化,比 inflateInit()多一個(gè)參數(shù): -MAX_WBITS,表示處理raw deflate數(shù)據(jù)。因?yàn)間zip數(shù)據(jù)中的zlib壓縮數(shù)據(jù)塊沒(méi)有zlib header的兩個(gè)字節(jié)。使用inflateInit2時(shí)要求zlib庫(kù)忽略zlib header。在zlib手冊(cè)中要求windowBits為8..15,但是實(shí)際上其它范圍的數(shù)據(jù)有特殊作用,見(jiàn)zlib.h中的注釋,如負(fù)數(shù)表示raw deflate。Apache的deflate變種可能也沒(méi)有zlib header,需要添加假頭后處理。即MS的錯(cuò)誤deflate (raw deflate).zlib頭第1字節(jié)一般是0x78, 第2字節(jié)與第一字節(jié)合起來(lái)的雙字節(jié)應(yīng)能被31整除,詳見(jiàn)rfc1950。例如Firefox的zlib假頭為0x7801,python zlib.comPRess()結(jié)果頭部為0x789c。deflate 是最基礎(chǔ)的算法,gzip 在 deflate 的 raw data 前增加了 10 個(gè)字節(jié)的 gzheader,尾部添加了 8 個(gè)字節(jié)的校驗(yàn)字節(jié)(可選 crc32 和 adler32) 和長(zhǎng)度標(biāo)識(shí)字節(jié)。

問(wèn)題到這里看似已經(jīng)清晰了,但是依然有一個(gè)疑點(diǎn),就是我之前模擬登陸網(wǎng)站的時(shí)候一直會(huì)設(shè)置這個(gè)header請(qǐng)求頭,但是返回的數(shù)據(jù)卻不是壓縮過(guò)的.這看起來(lái)有些矛盾,經(jīng)過(guò)進(jìn)一步收集資料得知,瀏覽器中的都是會(huì)自動(dòng)進(jìn)行解壓縮的,故請(qǐng)求頭中都會(huì)加入這么一個(gè)編碼設(shè)置,并且網(wǎng)站的服務(wù)端并不是都支持這個(gè)請(qǐng)求頭參數(shù),也就是說(shuō)即便在請(qǐng)求頭中加入這么一個(gè)壓縮設(shè)置,服務(wù)器端返回?cái)?shù)據(jù)的時(shí)候也不一定會(huì)進(jìn)行壓縮才返回..至此疑問(wèn)都清除..

然后接下來(lái)就好辦了,既然知道了問(wèn)題的原因,那么我們用httpclient進(jìn)行接收的時(shí)候也就好處理了,如果對(duì)方支持gzip壓縮處理且我們的請(qǐng)求頭中也加入的gzip壓縮請(qǐng)求頭,那么返回header中會(huì)有這么一個(gè)返回頭信息:

Content-Encoding  gzip

我們?cè)诮邮辗祷匦畔⒌臅r(shí)候只需要稍微檢測(cè)一下返回頭中是否含有以上信息就可以進(jìn)行相應(yīng)的處理了,一段示例代碼如下:

HttpResponse rep = client.execute(post);Header[] headers = rep.getHeaders("Content-Encoding");boolean isGzip = false;for(Header h:headers){    if(h.getValue().equals("gzip")){            //返回頭中含有g(shù)zip            isGzip = true;       }}String responseString = null;if(isGzip){    //需要進(jìn)行g(shù)zip解壓處理    responseString = EntityUtils.toString(new GzipDecompressingEntity(rep.getEntity()));}else{    responseString = EntityUtils.toString(rep.getEntity());}

至此那個(gè)讓人抓狂的粗體方塊亂碼問(wèn)題解決完畢..

 

 


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 桑日县| 苏尼特左旗| 巴林右旗| 静海县| 原平市| 镇沅| 榕江县| 兴业县| 道真| 郑州市| 杭州市| 武隆县| 施甸县| 临夏市| 开封县| 周宁县| 南乐县| 泸水县| 阜南县| 台湾省| 丘北县| 枞阳县| 札达县| 金山区| 云阳县| 青铜峡市| 进贤县| 巨野县| 盱眙县| 湾仔区| 平遥县| 四会市| 扶余县| 汝阳县| 宁海县| 白沙| 长武县| 襄城县| 涞源县| 湖北省| 永靖县|