昨天發(fā)文后,蟒蛇群里有讀者反饋“吃錯藥了吧,基礎(chǔ)知識群里怎么發(fā)爬蟲教學(xué)呢”,后邊沒有人再去回復(fù)他… 也有讀者反饋“學(xué)爬蟲是蟒蛇書看完,買權(quán)威指南還是開發(fā)實戰(zhàn)”,然后就有其他讀者小伙伴跟他展開了討論和交流,彼此在陪伴鼓勵著對方… 其實我更偏向于積極正向的反饋,這種積極正向影響的是群里好幾百人,同時也會鼓舞著我,這對于我來說也有更新文章的動力。 看書和學(xué)習(xí)一個新東西是需要熱情和堅持的。剛開始的時候不難,是因為新鮮感,有滿腔的熱情;越到后邊越難,是因為知識都是由淺入深的,更何況我們的新鮮感和熱情都在逐漸衰退。所以伴讀群的存在是為了讓大家在學(xué)習(xí)的時候,找到同伴,共同堅持,走得更遠~ 如果大家有想要了解的內(nèi)容,可以在群里告訴小助手,我們針對這些問題可以有文章的產(chǎn)出,也可以有直播的分享,非常期待大家的反饋??! 大家在討論編寫網(wǎng)絡(luò)爬蟲程序的時候會用到 HTTP 協(xié)議的各方面知識,群里有大家提到了“ HTTP 網(wǎng)絡(luò)協(xié)議建議買《圖解 HTTP 協(xié)議》,網(wǎng)上說簡單易懂”。 那今天就跟大家分享一下 HTTP 相關(guān)的知識吧~ 為了理解 HTTP,我們有必要事先了解一下 TCP/IP 協(xié)議族。通常使用的網(wǎng)絡(luò)(包括互聯(lián)網(wǎng))是在 TCP/IP 協(xié)議族的基礎(chǔ)上運作的。而 HTTP 屬于它內(nèi)部的一個子集。 像這樣把與互聯(lián)網(wǎng)相關(guān)聯(lián)的協(xié)議集合起來總稱為 TCP/IP。 與 HTTP 關(guān)系密切的協(xié)議:IP、TCP 和 DNS負責傳輸?shù)?IP 協(xié)議IP(Internet Protocol)網(wǎng)際協(xié)議位于網(wǎng)絡(luò)層。Internet Protocol 這個名稱可能聽起來有點夸張,但事實正是如此,因為幾乎所有使用網(wǎng)絡(luò)的系統(tǒng)都會用到 IP 協(xié)議。 IP 協(xié)議的作用是把各種數(shù)據(jù)包傳送給對方。而要保證確實傳送到對方那里,則需要滿足各類條件。其中兩個重要的條件是 IP 地址和 MAC地址(Media Access Control Address)。IP 地址可變換,但 MAC 地址基本上不會更改。 在到達通信目標前的中轉(zhuǎn)過程中,那些計算機和路由器等網(wǎng)絡(luò)設(shè)備只能獲悉很粗略的傳輸路線。無論哪臺計算機、哪臺網(wǎng)絡(luò)設(shè)備,它們都無法全面掌握互聯(lián)網(wǎng)中的細節(jié)。 確??煽啃缘?TCP 協(xié)議TCP 位于傳輸層,提供可靠的字節(jié)流服務(wù)。TCP 協(xié)議為了更容易傳送大數(shù)據(jù)才把數(shù)據(jù)分割,而且 TCP 協(xié)議能夠確認數(shù)據(jù)最終是否送達到對方。 為了準確無誤地將數(shù)據(jù)送達目標處,TCP 協(xié)議采用了三次握手(three-way handshaking)策略。用 TCP 協(xié)議把數(shù)據(jù)包送出去后,TCP 不會對傳送后的情況置之不理,它一定會向?qū)Ψ酱_認是否成功送達。握手過程中使用了 TCP 的標志(flag)——SYN(synchronize)和 ACK(acknowledgement)。 若在握手過程中某個階段莫名中斷,TCP 協(xié)議會再次以相同的順序發(fā)送相同的數(shù)據(jù)包。 負責域名解析的 DNS 服務(wù)DNS(Domain Name System)服務(wù)是和 HTTP 協(xié)議一樣位于應(yīng)用層的協(xié)議。它提供域名到 IP 地址之間的解析服務(wù)。 計算機既可以被賦予 IP 地址,也可以被賦予主機名和域名。比如 www.hackr.jp。 用戶通常使用主機名或域名來訪問對方的計算機,而不是直接通過 IP 地址訪問。因為與 IP 地址的一組純數(shù)字相比,用字母配合數(shù)字的表示形式來指定計算機名更符合人類的記憶習(xí)慣。 但要讓計算機去理解名稱,相對而言就變得困難了。因為計算機更擅長處理一長串數(shù)字。 為了解決上述的問題,DNS 服務(wù)應(yīng)運而生。DNS 協(xié)議提供通過域名查找 IP 地址,或逆向從 IP 地址反查域名的服務(wù)。 各種協(xié)議與 HTTP 協(xié)議的關(guān)系我們通過這張圖來了解下 IP 協(xié)議、TCP 協(xié)議和 DNS 服務(wù)在使用 HTTP 協(xié)議的通信過程中各自發(fā)揮了哪些作用。 HTTP 協(xié)議用于客戶端和服務(wù)器端之間的通信HTTP 協(xié)議和 TCP/IP 協(xié)議族內(nèi)的其他眾多的協(xié)議相同,用于客戶端和服務(wù)器之間的通信。 請求訪問文本或圖像等資源的一端稱為客戶端,而提供資源響應(yīng)的一端稱為服務(wù)器端。 在兩臺計算機之間使用 HTTP 協(xié)議通信時,在一條通信線路上必定有一端是客戶端,另一端則是服務(wù)器端。 有時候,按實際情況,兩臺計算機作為客戶端和服務(wù)器端的角色有可能會互換。但就僅從一條通信路線來說,服務(wù)器端和客戶端的角色是確定的,而用 HTTP 協(xié)議能夠明確區(qū)分哪端是客戶端,哪端是服務(wù)器端。 通過請求和響應(yīng)的交換達成通信HTTP 協(xié)議規(guī)定,請求從客戶端發(fā)出,最后服務(wù)器端響應(yīng)該請求并返回。換句話說,肯定是先從客戶端開始建立通信的,服務(wù)器端在沒有接收到請求之前不會發(fā)送響應(yīng)。 下面,我們來看一個具體的示例。 下面則是從客戶端發(fā)送給某個 HTTP 服務(wù)器端的請求報文中的內(nèi)容。 GET /index.htm HTTP/1.1 起 始 行 開 頭 的 GET 表 示 請 求 訪 問 服 務(wù) 器 的 類 型, 稱 為 方 法(method)。隨后的字符串 /index.htm 指明了請求訪問的資源對象,也叫做請求 URI(request-URI)。最后的 HTTP/1.1,即 HTTP 的版本號,用來提示客戶端使用的 HTTP 協(xié)議功能。 綜合來看,這段請求內(nèi)容的意思是:請求訪問某臺 HTTP 服務(wù)器上的 /index.htm 頁面資源。 請求報文是由請求方法、請求 URI、協(xié)議版本、可選的請求首部字段和內(nèi)容實體構(gòu)成的。 接收到請求的服務(wù)器,會將請求內(nèi)容的處理結(jié)果以響應(yīng)的形式返回。
在起始行開頭的 HTTP/1.1 表示服務(wù)器對應(yīng)的 HTTP 版本。緊挨著的 200 OK 表示請求的處理結(jié)果的狀態(tài)碼(status code)和原因短語(reason-phrase)。下一行顯示了創(chuàng)建響應(yīng)的日期時間,是首部字 段(header field)內(nèi)的一個屬性。 接著以一空行分隔,之后的內(nèi)容稱為資源實體的主體(entity body)。 響應(yīng)報文基本上由協(xié)議版本、狀態(tài)碼(表示請求成功或失敗的數(shù)字代碼)、用以解釋狀態(tài)碼的原因短語、可選的響應(yīng)首部字段以及實體主體構(gòu)成。稍后我們會對這些內(nèi)容進行詳細說明。 HTTP 是不保存狀態(tài)的協(xié)議HTTP 是一種不保存狀態(tài),即無狀態(tài)(stateless)協(xié)議。HTTP 協(xié)議自身不對請求和響應(yīng)之間的通信狀態(tài)進行保存。也就是說在 HTTP 這個級別,協(xié)議對于發(fā)送過的請求或響應(yīng)都不做持久化處理。 使用 HTTP 協(xié)議,每當有新的請求發(fā)送時,就會有對應(yīng)的新響應(yīng)產(chǎn)生。協(xié)議本身并不保留之前一切的請求或響應(yīng)報文的信息。這是為了更快地處理大量事務(wù),確保協(xié)議的可伸縮性,而特意把 HTTP 協(xié)議設(shè)計成如此簡單的。 可是,隨著 Web 的不斷發(fā)展,因無狀態(tài)而導(dǎo)致業(yè)務(wù)處理變得棘手的情況增多了。比如,用戶登錄到一家購物網(wǎng)站,即使他跳轉(zhuǎn)到該站的其他頁面后,也需要能繼續(xù)保持登錄狀態(tài)。針對這個實例,網(wǎng)站為了能夠掌握是誰送出的請求,需要保存用戶的狀態(tài)。 HTTP/1.1 雖然是無狀態(tài)協(xié)議,但為了實現(xiàn)期望的保持狀態(tài)功能,于是引入了 Cookie 技術(shù)。有了 Cookie 再用 HTTP 協(xié)議通信,就可以管理狀態(tài)了。 請求 URI 定位資源HTTP 協(xié)議使用 URI 定位互聯(lián)網(wǎng)上的資源。正是因為 URI 的特定功能,在互聯(lián)網(wǎng)上任意位置的資源都能訪問到。 當客戶端請求訪問資源而發(fā)送請求時,URI 需要將作為請求報文中的請求URI 包含在內(nèi)。指定請求 URI 的方式有很多。 告知服務(wù)器意圖的 HTTP 方法
使用方法下達命令向請求 URI 指定的資源發(fā)送請求報文時,采用稱為方法的命令。方法的作用在于,可以指定請求的資源按期望產(chǎn)生某種行為。方法中有 GET、POST 和 HEAD 等。 持久連接節(jié)省通信量HTTP 協(xié)議的初始版本中,每進行一次 HTTP 通信就要斷開一次 TCP 連接。以當年的通信情況來說,因為都是些容量很小的文本傳輸,所以即使這樣也沒有多大問題??呻S著 HTTP 的普及,文檔中包含大量圖片的情況多了起來。 比如,使用瀏覽器瀏覽一個包含多張圖片的 HTML 頁面時,在發(fā)送請求訪問 HTML 頁面資源的同時,也會請求該 HTML 頁面里包含的其他資源。因此,每次的請求都會造成無謂的 TCP 連接建立和斷開,增加通信量的開銷。 持久連接為解決上述 TCP 連接的問題,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久連接(HTTP Persistent Connections,也稱為 HTTP keep-alive 或 HTTP connection reuse)的方法。持久連接的特點是,只要任意一端沒有明確提出斷開連接,則保持 TCP 連接狀態(tài)。 持久連接的好處在于減少了 TCP 連接的重復(fù)建立和斷開所造成的額外開銷,減輕了服務(wù)器端的負載。另外,減少開銷的那部分時間,使 HTTP 請求和響應(yīng)能夠更早地結(jié)束,這樣 Web 頁面的顯示速度也就相應(yīng)提高了。 在 HTTP/1.1 中,所有的連接默認都是持久連接,但在 HTTP/1.0 內(nèi)并未標準化。雖然有一部分服務(wù)器通過非標準的手段實現(xiàn)了持久連接,但服務(wù)器端不一定能夠支持持久連接。毫無疑問,除了服務(wù)器端,客戶端也需要支持持久連接。 管線化持久連接使得多數(shù)請求以管線化(pipelining)方式發(fā)送成為可能。從前發(fā)送請求后需等待并收到響應(yīng),才能發(fā)送下一個請求。管線化技術(shù)出現(xiàn)后,不用等待響應(yīng)亦可直接發(fā)送下一個請求。 這樣就能夠做到同時并行發(fā)送多個請求,而不需要一個接一個地等待響應(yīng)了。 當請求一個包含 10 張圖片的 HTML Web 頁面,與挨個連接相比,用持久連接可以讓請求更快結(jié)束。而管線化技術(shù)則比持久連接還要快。請求數(shù)越多,時間差就越明顯。 使用 Cookie 的狀態(tài)管理HTTP 是無狀態(tài)協(xié)議,它不對之前發(fā)生過的請求和響應(yīng)的狀態(tài)進行管理。也就是說,無法根據(jù)之前的狀態(tài)進行本次的請求處理。 假設(shè)要求登錄認證的 Web 頁面本身無法進行狀態(tài)的管理(不記錄已登錄的狀態(tài)),那么每次跳轉(zhuǎn)新頁面就要再次登錄,或者要在每次請求報文中附加參數(shù)來管理登錄狀態(tài)。 不可否認,無狀態(tài)協(xié)議當然也有它的優(yōu)點。由于不必保存狀態(tài),自然可減少服務(wù)器的 CPU 及內(nèi)存資源的消耗。從另一側(cè)面來說,也正是因為 HTTP 協(xié)議本身是非常簡單的,所以才會被應(yīng)用在各種場景里。 保留無狀態(tài)協(xié)議這個特征的同時又要解決類似的矛盾問題,于是引入了 Cookie 技術(shù)。Cookie 技術(shù)通過在請求和響應(yīng)報文中寫入 Cookie 信息來控制客戶端的狀態(tài)。 Cookie 會根據(jù)從服務(wù)器端發(fā)送的響應(yīng)報文內(nèi)的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存 Cookie。當下次客戶端再往該服務(wù)器發(fā)送請求時,客戶端會自動在請求報文中加入 Cookie 值后發(fā)送出去。 服務(wù)器端發(fā)現(xiàn)客戶端發(fā)送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發(fā)來的連接請求,然后對比服務(wù)器上的記錄,最后得到之前的狀態(tài)信息。 上圖展示了發(fā)生 Cookie 交互的情景,HTTP 請求報文和響應(yīng)報文的內(nèi)容如下。①請求報文(沒有 Cookie 信息的狀態(tài)) GET /reader/ HTTP/1.1 ②響應(yīng)報文(服務(wù)器端生成 Cookie 信息)
③請求報文(自動發(fā)送保存著的 Cookie 信息) GET /image/ HTTP/1.1 好啦,今天的內(nèi)容就分享到這里,主要是 HTTP 協(xié)議相關(guān)的基礎(chǔ)知識,其實 HTTP 協(xié)議本身并不復(fù)雜,理解起來也不會花費太多學(xué)習(xí)成本,但純概念式的學(xué)習(xí)稍顯單調(diào)。前端工程師也許對各種具有炫酷效果的頁面的實現(xiàn)技巧、賞心悅目的 UI 框架更感興趣,但因此常常忽視了 HTTP 協(xié)議這部分基礎(chǔ)內(nèi)容。實際上,如果想要在專業(yè)技術(shù)道路上走得更堅實,絕對不能繞開學(xué)習(xí) HTTP 協(xié)議這一環(huán)節(jié)。對基礎(chǔ)及核心部分的深入學(xué)習(xí)是成為一名專業(yè)技術(shù)人員的前提,以不變應(yīng)萬變才是立足之本。 以上內(nèi)容來自《圖解 HTTP》,目前,國內(nèi)講解 HTTP 協(xié)議的書實在太少了。本書作者的寫作手法平實易懂,內(nèi)容講解透徹到位,圖文并茂,大量圖片穿插文中,生動形象地向讀者介紹每一個應(yīng)用案例,減少了讀者閱讀時的枯燥感。借助一張張配圖,讀者們不僅會加深視覺記憶,在輕松愉悅的氛圍中,還可以更深刻地理解通信機制等背后的工作原理。 如果你還沒有這本書,可以戳下方卡片進行購買~ |
|
來自: redwineczy > 《待分類》