摘要:分塊傳輸編碼分塊傳輸編碼是超文本傳輸協(xié)議中的一種數(shù)據(jù)傳輸機(jī)制,允許由網(wǎng)頁(yè)服務(wù)器發(fā)送給客戶(hù)端應(yīng)用通常是網(wǎng)頁(yè)瀏覽器的數(shù)據(jù)可以分成多個(gè)部分。分塊傳輸編碼只在協(xié)議版本中提供。
實(shí)習(xí)中的一個(gè)主要工作就是分析 HTTP 中的協(xié)議,自己也用 Python 寫(xiě)過(guò)正則表達(dá)式對(duì) HTTP 請(qǐng)求和響應(yīng)的內(nèi)容進(jìn)行匹配,然后把關(guān)鍵字段抽離出來(lái)放到一個(gè)字典中以備使用(可以稍微改造一下就是一個(gè)爬蟲(chóng)工具)。
HTTP 協(xié)議中的很多坑,自己都遇到過(guò),我就針對(duì)自己遇到的幾種 HTTP 常見(jiàn)的數(shù)據(jù)格式,來(lái)做一個(gè)總結(jié)。
Zlib 壓縮數(shù)據(jù)對(duì)于 Zlib,一點(diǎn)也不陌生,我們平時(shí)用它來(lái)壓縮文件,常見(jiàn)類(lèi)型有 zip、rar 和 7z 等。Zlib 是一種流行的文件壓縮算法,應(yīng)用十分廣泛,尤其是在 Linux 平臺(tái)。當(dāng)應(yīng)用 Zlib 壓縮到一個(gè)純文本文件時(shí),效果是非常明顯的,大約可以減少70%以上的文件大小,這取決于文件中的內(nèi)容。
Zlib 也適用于 Web 數(shù)據(jù)傳輸,比如利用 Apache 中的 Gzip (后面會(huì)提到,一種壓縮算法) 模塊,我們可以使用 Gzip 壓縮算法來(lái)對(duì) Apache 服務(wù)器發(fā)布的網(wǎng)頁(yè)內(nèi)容進(jìn)行壓縮后再傳輸?shù)娇蛻?hù)端瀏覽器。這樣經(jīng)過(guò)壓縮后實(shí)際上降低了網(wǎng)絡(luò)傳輸?shù)淖止?jié)數(shù),最明顯的好處就是可以加快網(wǎng)頁(yè)加載的速度。
網(wǎng)頁(yè)加載速度加快的好處不言而喻,節(jié)省流量,改善用戶(hù)的瀏覽體驗(yàn)。而這些好處并不僅僅限于靜態(tài)內(nèi)容,PHP 動(dòng)態(tài)頁(yè)面和其他動(dòng)態(tài)生成的內(nèi)容均可以通過(guò)使用 Apache 壓縮模塊壓縮,加上其他的性能調(diào)整機(jī)制和相應(yīng)的服務(wù)器端 緩存規(guī)則,這可以大大提高網(wǎng)站的性能。因此,對(duì)于部署在 Linux 服務(wù)器上的 PHP 程序,在服務(wù)器支持的情況下,建議你開(kāi)啟使用 Gzip Web 壓縮。
Gzip 壓縮兩種類(lèi)型壓縮算法不同,可以產(chǎn)生不同的壓縮數(shù)據(jù)(目的都是為了減小文件大小)。目前 Web 端流行的壓縮格式有兩種,分別是 Gzip 和 Defalte。
Apache 中的就是 Gzip 模塊,Deflate 是同時(shí)使用了 LZ77 算法與哈夫曼編碼(Huffman Coding)的一個(gè)無(wú)損數(shù)據(jù)壓縮算法。Deflate 壓縮與解壓的源代碼可以在自由、通用的壓縮庫(kù) zlib 上找到。
更高壓縮率的 Deflate 是 7-zip 所實(shí)現(xiàn)的。AdvanceCOMP 也使用這種實(shí)現(xiàn),它可以對(duì) gzip、PNG、MNG 以及 ZIP 文件進(jìn)行壓縮從而得到比 zlib 更小的文件大小。在 Ken Silverman的 KZIP 與 PNGOUT 中使用了一種更加高效同時(shí)要求更多用戶(hù)輸入的 Deflate 程序。
deflate 使用 inflateInit(),而 gzip 使用 inflateInit2() 進(jìn)行初始化,比 inflateInit() 多一個(gè)參數(shù): -MAX_WBITS,表示處理 raw deflate 數(shù)據(jù)。因?yàn)?gzip 數(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ù)有特殊作用,如負(fù)數(shù)表示 raw deflate。
其實(shí)說(shuō)這么多,總結(jié)一句話(huà),Deflate 是一種壓縮算法,是 huffman 編碼的一種加強(qiáng)。 deflate 與 gzip 解壓的代碼幾乎相同,可以合成一塊代碼。
更多知識(shí)請(qǐng)見(jiàn) 維基百科 zlib。
Web 服務(wù)器處理數(shù)據(jù)壓縮的過(guò)程Web服務(wù)器接收到瀏覽器的HTTP請(qǐng)求后,檢查瀏覽器是否支持HTTP壓縮(Accept-Encoding 信息);
如果瀏覽器支持HTTP壓縮,Web服務(wù)器檢查請(qǐng)求文件的后綴名;
如果請(qǐng)求文件是HTML、CSS等靜態(tài)文件,Web服務(wù)器到壓縮緩沖目錄中檢查是否已經(jīng)存在請(qǐng)求文件的最新壓縮文件;
如果請(qǐng)求文件的壓縮文件不存在,Web服務(wù)器向?yàn)g覽器返回未壓縮的請(qǐng)求文件,并在壓縮緩沖目錄中存放請(qǐng)求文件的壓縮文件;
如果請(qǐng)求文件的最新壓縮文件已經(jīng)存在,則直接返回請(qǐng)求文件的壓縮文件;
如果請(qǐng)求文件是動(dòng)態(tài)文件,Web服務(wù)器動(dòng)態(tài)壓縮內(nèi)容并返回瀏覽器,壓縮內(nèi)容不存放到壓縮緩存目錄中。
舉個(gè)栗子說(shuō)了這么多,下面舉一個(gè)例子,打開(kāi)抓包軟件,訪問(wèn)我們學(xué)校的官網(wǎng)( www.ecnu.edu.cn ),請(qǐng)求頭如下:
GET /_css/tpl2/system.css HTTP/1.1 Host: www.ecnu.edu.cn Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36 Accept: text/css,*/*;q=0.1 Referer: http://www.ecnu.edu.cn/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.8 Cookie: a10-default-cookie-persist-20480-sg_bluecoat_a=AFFIHIMKFAAA
在第七行, Accept-Encoding 顯示的是 gzip, deflate,這句話(huà)的意思是,瀏覽器告訴服務(wù)器支持 gzip 和 deflate 兩種數(shù)據(jù)格式,服務(wù)器收到這種請(qǐng)求之后,會(huì)進(jìn)行 gzip 或 deflate 壓縮(一般都是返回 gzip 格式的數(shù)據(jù))。
Python 的 urllib2 就可以設(shè)置這個(gè)參數(shù):
request = urllib2.Request(url) request.add_header("Accept-encoding", "gzip") //或者設(shè)置成 deflate request.add_header("Accept-encoding", "deflate") //或者兩者都設(shè)置 request.add_header("Accept-encoding", "gzip, deflate")
服務(wù)器給的響應(yīng)一般如下:
HTTP/1.1 200 OK Date: Sat, 22 Oct 2016 11:41:19 GMT Content-Type: text/javascript;charset=utf-8 Transfer-Encoding: chunked Connection: close Vary: Accept-Encoding tracecode: 24798560510951725578102219 Server: Apache Content-Encoding: gzip 400a ............ks#I. ...W...,....>..T..]..Z...Y..].MK..2..L..(略) //響應(yīng)體為壓縮數(shù)據(jù)
從響應(yīng)頭來(lái)看,Content-Encoding: gzip 這段話(huà)說(shuō)明響應(yīng)體的壓縮方式是 gzip 壓縮,一般有幾種情況,字段為空表示明文無(wú)壓縮,還有 Content-Encoding: gzip 和 Content-Encoding: deflate 兩種。
實(shí)際上 Gzip 網(wǎng)站要遠(yuǎn)比 Deflate 多,之前寫(xiě)過(guò)一個(gè)簡(jiǎn)單爬蟲(chóng)從 hao123的主頁(yè)開(kāi)始爬,爬幾千個(gè)網(wǎng)頁(yè)(基本涵蓋所有常用的),專(zhuān)門(mén)分析響應(yīng)體的壓縮類(lèi)型,得到的結(jié)果是:
Accept-Encoding 不設(shè)置參數(shù):會(huì)返回一個(gè)無(wú)壓縮的響應(yīng)體(瀏覽器比較特別,他們會(huì)自動(dòng)設(shè)置 Accept-Encoding: gzip: deflate 來(lái)提高傳輸速度);
Accept-Encoding: gzip,100% 的網(wǎng)站都會(huì)返回 gzip 壓縮,但不保證互聯(lián)網(wǎng)所有網(wǎng)站都支持 gzip(萬(wàn)一沒(méi)開(kāi)啟);
Accept-Encoding: deflate:只有不到 10% 的網(wǎng)站返回一個(gè) deflate 壓縮的響應(yīng),其他的則返回一個(gè)沒(méi)有壓縮的響應(yīng)體。
Accept-Encoding: gzip, deflate:返回的結(jié)果也都是 gzip 格式的數(shù)據(jù),說(shuō)明在優(yōu)先級(jí)上 gzip 更受歡迎。
響應(yīng)頭的 Encoding 字段很有幫助,比如我們寫(xiě)個(gè)正則表達(dá)式匹配響應(yīng)頭是什么壓縮:
(?<=Content-Encoding: ).+(?= )
匹配到內(nèi)容為空說(shuō)明沒(méi)有壓縮,為 gzip 說(shuō)明響應(yīng)體要經(jīng)過(guò) gzip 解壓,為 deflate 說(shuō)明為 deflate 壓縮。
Python 中的 zlib 庫(kù)在python中有zlib庫(kù),它可以解決gzip、deflate和zlib壓縮。這三種對(duì)應(yīng)的壓縮方式分別是:
RFC 1950 (zlib compressed format) RFC 1951 (deflate compressed format) RFC 1952 (gzip compressed format)
雖說(shuō)是 Python 庫(kù),但是底層還是 C(C++) 來(lái)實(shí)現(xiàn)的,這個(gè) http-parser 也是 C 實(shí)現(xiàn)的源碼,Nodejs 的 http-parser 也是 C 實(shí)現(xiàn)的源碼,zlib 的 C 源碼在這里。C 真的好牛逼呀!
在解壓縮的過(guò)程中,需要選擇 windowBits 參數(shù):
to (de-)compress deflate format, use wbits = -zlib.MAX_WBITS to (de-)compress zlib format, use wbits = zlib.MAX_WBITS to (de-)compress gzip format, use wbits = zli
例如,解壓gzip數(shù)據(jù),就可以使用zlib.decompress(data, zlib.MAX_WBITS | 16),解壓deflate數(shù)據(jù)可以使用zlib.decompress(data,- zlib.MAX_WBITS)。
當(dāng)然,對(duì)于gzip文件,也可以使用python的gzip包來(lái)解決,可以參考下面的代碼:
>>> import gzip >>> import StringIO >>> fio = StringIO.StringIO(gzip_data) >>> f = gzip.GzipFile(fileobj=fio) >>> f.read() "test" >>> f.close()
也可以在解壓的時(shí)候自動(dòng)加入頭檢測(cè),把32加入頭中就可以觸發(fā)頭檢測(cè),例如:
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32) "test" >>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32) "test"
以上參考 stackoverflow How can I decompress a gzip stream with zlib?。
剛接觸這些東西的時(shí)候,每天都會(huì)稀奇古怪的報(bào)一些錯(cuò)誤,基本上 Google 一下都能解決。
分塊傳輸編碼 chunked分塊傳輸編碼(Chunked transfer encoding)是超文本傳輸協(xié)議(HTTP)中的一種數(shù)據(jù)傳輸機(jī)制,允許 HTTP 由網(wǎng)頁(yè)服務(wù)器發(fā)送給客戶(hù)端應(yīng)用( 通常是網(wǎng)頁(yè)瀏覽器)的數(shù)據(jù)可以分成多個(gè)部分。分塊傳輸編碼只在 HTTP 協(xié)議 1.1 版本(HTTP/1.1)中提供。
通常,HTTP 應(yīng)答消息中發(fā)送的數(shù)據(jù)是整個(gè)發(fā)送的,Content-Length 消息頭字段表示數(shù)據(jù)的長(zhǎng)度。數(shù)據(jù)的長(zhǎng)度很重要,因?yàn)榭蛻?hù)端需要知道哪里是應(yīng)答消息的結(jié)束,以及后續(xù)應(yīng)答消息的開(kāi)始。然而,使用分塊傳輸編碼,數(shù)據(jù)分解成一系列數(shù)據(jù)塊,并以一個(gè)或多個(gè)塊發(fā)送,這樣服務(wù)器可以發(fā)送數(shù)據(jù)而不需要預(yù)先知道發(fā)送內(nèi)容的總大小。通常數(shù)據(jù)塊的大小是一致的,但也不總是這種情況。
分塊傳輸?shù)膬?yōu)點(diǎn)HTTP 1.1引入分塊傳輸編碼提供了以下幾點(diǎn)好處:
HTTP 分塊傳輸編碼允許服務(wù)器為動(dòng)態(tài)生成的內(nèi)容維持 HTTP 持久鏈接。通常,持久鏈接需要服務(wù)器在開(kāi)始發(fā)送消息體前發(fā)送 Content-Length 消息頭字段,但是對(duì)于動(dòng)態(tài)生成的內(nèi)容來(lái)說(shuō),在內(nèi)容創(chuàng)建完之前是不可知的。
分塊傳輸編碼允許服務(wù)器在最后發(fā)送消息頭字段。對(duì)于那些頭字段值在內(nèi)容被生成之前無(wú)法知道的情形非常重要,例如消息的內(nèi)容要使用散列進(jìn)行簽名,散列的結(jié)果通過(guò) HTTP 消息頭字段進(jìn)行傳輸。沒(méi)有分塊傳輸編碼時(shí),服務(wù)器必須緩沖內(nèi)容直到完成后計(jì)算頭字段的值并在發(fā)送內(nèi)容前發(fā)送這些頭字段的值。
HTTP 服務(wù)器有時(shí)使用壓縮 (gzip 或 deflate)以縮短傳輸花費(fèi)的時(shí)間。分塊傳輸編碼可以用來(lái)分隔壓縮對(duì)象的多個(gè)部分。在這種情況下,塊不是分別壓縮的,而是整個(gè)負(fù)載進(jìn)行壓縮,壓縮的輸出使用本文描述的方案進(jìn)行分塊傳輸。在壓縮的情形中,分塊編碼有利于一邊進(jìn)行壓縮一邊發(fā)送數(shù)據(jù),而不是先完成壓縮過(guò)程以得知壓縮后數(shù)據(jù)的大小。
注:以上內(nèi)容來(lái)自于維基百科。
分塊傳輸?shù)母袷?/b>如果一個(gè) HTTP 消息(請(qǐng)求消息或應(yīng)答消息)的 Transfer-Encoding 消息頭的值為 chunked,那么,消息體由數(shù)量未定的塊組成,并以最后一個(gè)大小為 0 的塊為結(jié)束。
每一個(gè)非空的塊都以該塊包含數(shù)據(jù)的字節(jié)數(shù)(字節(jié)數(shù)以十六進(jìn)制表示)開(kāi)始,跟隨一個(gè) CRLF(回車(chē)及換行),然后是數(shù)據(jù)本身,最后塊 CRLF 結(jié)束。在一些實(shí)現(xiàn)中,塊大小和 CRLF 之間填充有白空格(0x20)。
最后一塊是單行,由塊大?。?),一些可選的填充白空格,以及 CRLF。最后一塊不再包含任何數(shù)據(jù),但是可以發(fā)送可選的尾部,包括消息頭字段。
消息最后以 CRLF 結(jié)尾。例如下面就是一個(gè) chunked 格式的響應(yīng)體。
HTTP/1.1 200 OK Date: Wed, 06 Jul 2016 06:59:55 GMT Server: Apache Accept-Ranges: bytes Transfer-Encoding: chunked Content-Type: text/html Content-Encoding: gzip Age: 35 X-Via: 1.1 daodianxinxiazai58:88 (Cdn Cache Server V2.0), 1.1 yzdx147:1 (Cdn Cache Server V2.0) Connection: keep-alive a ....k.|W.. 166 ..OO.0...&~..;........]..(F=V.A3.X..~z...-.l8......y....).?....,....j..h .6 ....s.~.>..mZ .8/..,.)B.G.`"Dq.P].f=0..Q..d.....h......8....F..y......q.....4 {F..M.A.*..a.rAra.... .n>.D ..o@.`^.....!@ $...p...%aD..K.. .d{2...UnF,C[....T.....c....V...."%.`U......? D....#..K..<.....D.e....IFK0.<...)]K.V/eK.Qz...^....t...S6...m...^..CK.XRU?m.. .........Z..#Uik...... 0
Transfer-Encoding: chunked字段可以看出響應(yīng)體是否為 chunked 壓縮,chunked 數(shù)據(jù)很有意思,采用的格式是 長(zhǎng)度 內(nèi)容 長(zhǎng)度 ..0 ,而且長(zhǎng)度還是十六進(jìn)制的,最后以 0 結(jié)尾(不保證都有)。因?yàn)樯厦娴臄?shù)據(jù)是 gzip 壓縮,看起來(lái)不夠直觀,下面舉個(gè)簡(jiǎn)單的例子:
5 ababa f 123451234512345 14 12345123451234512345 0
上述例子 chunked 解碼后的數(shù)據(jù) ababa12345...,另外 是不可見(jiàn)的,我手動(dòng)加的。
和 gzip 一樣,一樣可以寫(xiě)一個(gè)正則表達(dá)式來(lái)匹配:
(?<=Transfer-Encoding: ).+(?= )處理 chunked 數(shù)據(jù)
從前面的介紹可以知道,response-body 部分其實(shí)由 length(1) data(1) length(2) data(2)…… 循環(huán)組成,通過(guò)下面的函數(shù)進(jìn)行處理,再根據(jù)壓縮類(lèi)型解壓出最終的數(shù)據(jù)。
Python 處理的過(guò)程如下:
unchunked = b"" pos = 0 while pos <= len(data): chunkNumLen = data.find(b" ", pos)-pos //從第一個(gè)元素開(kāi)始,發(fā)現(xiàn)第一個(gè) ,計(jì)算length長(zhǎng)度 chunkLen=int(data[pos:pos+chunkNumLen], 16) //把length的長(zhǎng)度轉(zhuǎn)換成int if chunkLen == 0: break //如果長(zhǎng)度為0,則說(shuō)明到結(jié)尾 chunk = data[pos+chunkNumLen+len(" "):pos+chunkNumLen+len(" ")+chunkLen] unchunked += chunk //將壓縮數(shù)據(jù)拼接 pos += chunkNumLen+len(" ")+chunkLen+len(" ") //同時(shí)pos位置向后移動(dòng) return unchunked //此時(shí)處理后unchunked就是普通的壓縮數(shù)據(jù),可以用zlib解壓函數(shù)進(jìn)行解壓
實(shí)際中,我們會(huì)同時(shí)遇到既時(shí) chunked 又是壓縮數(shù)據(jù)的響應(yīng),這個(gè)時(shí)候處理的思路應(yīng)該是:先處理 chunked,在處理壓縮數(shù)據(jù),順序不能反。
MultiPart 數(shù)據(jù)MultiPart 的本質(zhì)就是 Post 請(qǐng)求,MultiPart出現(xiàn)在請(qǐng)求中,用來(lái)對(duì)一些文件(圖片或文檔)進(jìn)行處理,在請(qǐng)求頭中出現(xiàn) Content-Type: multipart/form-data; boundary=::287032381131322 則表示為 MultiPart 格式數(shù)據(jù)包,下面這個(gè)是 multipart 數(shù)據(jù)包格式:
POST /cgi-bin/qtest HTTP/1.1 Host: aram User-Agent: Mozilla/5.0 Gecko/2009042316 Firefox/3.0.10 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://aram/~martind/banner.htm Content-Type: multipart/form-data; boundary=::287032381131322 Content-Length: 514 --::287032381131322 Content-Disposition: form-data; name="datafile1"; filename="r.gif" Content-Type: image/gif GIF87a.............,...........D..; --::287032381131322 Content-Disposition: form-data; name="datafile2"; filename="g.gif" Content-Type: image/gif GIF87a.............,...........D..; --::287032381131322 Content-Disposition: form-data; name="datafile3"; filename="b.gif" Content-Type: image/gif GIF87a.............,...........D..; --::287032381131322—
http 協(xié)議本身的原始方法不支持 multipart/form-data 請(qǐng)求,那這個(gè)請(qǐng)求自然就是由這些原始的方法演變而來(lái)的,具體如何演變且看下文:
multipart/form-data 的基礎(chǔ)方法是 post,也就是說(shuō)是由 post 方法來(lái)組合實(shí)現(xiàn)的
multipart/form-data 與 post 方法的不同之處:請(qǐng)求頭,請(qǐng)求體。
multipart/form-data 的請(qǐng)求頭必須包含一個(gè)特殊的頭信息:Content-Type,且其值也必須規(guī)定為 multipart/form-data,同時(shí)還需要規(guī)定一個(gè)內(nèi)容分割符用于分割請(qǐng)求體中的多個(gè) post 內(nèi)容,如文件內(nèi)容和文本內(nèi)容自然需要分割,不然接收方就無(wú)法正常解析和還原這個(gè)文件。具體的頭信息如:Content-Type: multipart/form-data; boundary=${bound},${bound} 代表分割符,可以任意規(guī)定,但為了避免和正常文本重復(fù),盡量使用復(fù)雜一點(diǎn)的內(nèi)容,如::287032381131322
multipart/form-data 的請(qǐng)求體也是一個(gè)字符串,不過(guò)和 post 的請(qǐng)求體不同的是它的構(gòu)造方式,post 是簡(jiǎn)單的 name=value 值連接,而 multipart/form-data 則是添加了分隔符等內(nèi)容的構(gòu)造體。
維基百科上關(guān)于 multipart 的介紹。
multipart 的數(shù)據(jù)格式有一定的特點(diǎn),首先是頭部規(guī)定了一個(gè) ${bound},上面那個(gè)例子中的 ${bound} 為 ::287032381131322,由多個(gè)內(nèi)容相同的塊組成,每個(gè)塊的格式以--加 ${bound} 開(kāi)始的,然后是該部分內(nèi)容的描述信息,然后一個(gè) ,然后是描述信息的具體內(nèi)容。如果傳送的內(nèi)容是一個(gè)文件的話(huà),那么還會(huì)包含文件名信息,以及文件內(nèi)容的類(lèi)型。
小結(jié),要發(fā)送一個(gè) multipart/form-data 的請(qǐng)求,需要定義一個(gè)自己的 ${bound} ,按照格式來(lái)發(fā)請(qǐng)求就好,對(duì)于 multipart 的數(shù)據(jù)格式并沒(méi)有過(guò)多介紹,感覺(jué)和 chunked 很類(lèi)似,不難理解。
總結(jié)本文介紹的三種數(shù)據(jù)格式,都比較基礎(chǔ),一些框架自動(dòng)把它們處理,比如爬蟲(chóng)。還有圖像上傳,對(duì)于 multipart/data 格式的請(qǐng)求頭,了解一些概念性的東西也非常有意思。共勉。
參考全列在文章中了
歡迎來(lái)我的博客交流。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/44259.html
摘要:一般使用請(qǐng)求方法向服務(wù)器發(fā)送數(shù)據(jù)主要是一些創(chuàng)建更新操作,本文討論的是請(qǐng)求方法常用的四種數(shù)據(jù)提交格式。其實(shí)就是和請(qǐng)求的數(shù)據(jù)提交格式是一樣的,只不過(guò)位置從上換到了里。適用場(chǎng)景數(shù)據(jù)量不大數(shù)據(jù)層級(jí)不深的情況下強(qiáng)烈建議這種數(shù)據(jù)提交格式。 本文所講的 POST 請(qǐng)求是 HTTP/1.1 協(xié)議中規(guī)定的眾多 HTTP 請(qǐng)求方法的其中最常用的一個(gè)。一般使用 POST 請(qǐng)求方法向服務(wù)器發(fā)送數(shù)據(jù)(主要是一些...
摘要:主要是整理一些自己還記得的面試題。標(biāo)注重點(diǎn)的是頻繁出現(xiàn)的,也確實(shí)很重要的知識(shí)點(diǎn)??傊疃壤斫馀e一反三邏輯清晰表達(dá)流暢。以上,僅供參考。 主要是整理一些自己還記得的面試題。很多題目會(huì)根據(jù)項(xiàng)目?jī)?nèi)容提問(wèn),現(xiàn)在只記得一些比較常規(guī)的問(wèn)題,后面想起來(lái)會(huì)做一些補(bǔ)充。標(biāo)注重點(diǎn)的是頻繁出現(xiàn)的,也確實(shí)很重要的知識(shí)點(diǎn)。 css 盒子模型:ie與其他瀏覽器的區(qū)別,如何改變盒子模型 圖形:實(shí)現(xiàn)扇形/圓環(huán)/梯...
摘要:主要是整理一些自己還記得的面試題。標(biāo)注重點(diǎn)的是頻繁出現(xiàn)的,也確實(shí)很重要的知識(shí)點(diǎn)??傊疃壤斫馀e一反三邏輯清晰表達(dá)流暢。以上,僅供參考。 主要是整理一些自己還記得的面試題。很多題目會(huì)根據(jù)項(xiàng)目?jī)?nèi)容提問(wèn),現(xiàn)在只記得一些比較常規(guī)的問(wèn)題,后面想起來(lái)會(huì)做一些補(bǔ)充。標(biāo)注重點(diǎn)的是頻繁出現(xiàn)的,也確實(shí)很重要的知識(shí)點(diǎn)。 css 盒子模型:ie與其他瀏覽器的區(qū)別,如何改變盒子模型 圖形:實(shí)現(xiàn)扇形/圓環(huán)/梯...
摘要:主要是整理一些自己還記得的面試題。標(biāo)注重點(diǎn)的是頻繁出現(xiàn)的,也確實(shí)很重要的知識(shí)點(diǎn)。總之要深度理解舉一反三邏輯清晰表達(dá)流暢。以上,僅供參考。 主要是整理一些自己還記得的面試題。很多題目會(huì)根據(jù)項(xiàng)目?jī)?nèi)容提問(wèn),現(xiàn)在只記得一些比較常規(guī)的問(wèn)題,后面想起來(lái)會(huì)做一些補(bǔ)充。標(biāo)注重點(diǎn)的是頻繁出現(xiàn)的,也確實(shí)很重要的知識(shí)點(diǎn)。 css 盒子模型:ie與其他瀏覽器的區(qū)別,如何改變盒子模型 圖形:實(shí)現(xiàn)扇形/圓環(huán)/梯...
閱讀 2116·2021-11-24 09:39
閱讀 1602·2021-10-11 10:59
閱讀 2533·2021-09-24 10:28
閱讀 3409·2021-09-08 09:45
閱讀 1298·2021-09-07 10:06
閱讀 1699·2019-08-30 15:53
閱讀 2105·2019-08-30 15:53
閱讀 1443·2019-08-30 15:53