淺談 HTTP 協(xié)議

本文為原創(chuàng)作品甲葬。歡迎轉(zhuǎn)載撇寞,轉(zhuǎn)載請注明出處:林東洲的博客 | Lindz Blog敢订。

作為一個(gè) Weber资厉,掌握必要的 HTTP/TCP 等協(xié)議十分必要厅缺。自從上學(xué)期學(xué)習(xí)了計(jì)算機(jī)網(wǎng)絡(luò),對于網(wǎng)絡(luò)這一塊有了一定的了解,再加上網(wǎng)上學(xué)習(xí)到的知識湘捎,通過本文記錄自己對 HTTP 協(xié)議的理解诀豁。

首先讓我們從一個(gè)問題入手,當(dāng)我們在瀏覽器中輸入 http://www.baidu.com 訪問百度的時(shí)候?yàn)g覽器做了哪些事情窥妇。(這里以 Chrome 瀏覽器為例)

  1. 首先 Chrome 搜索自身的 DNS 緩存舷胜。

如果 DNS 緩存中找到百度的IP地址,就跳過了接下來查找IP地址步驟活翩,直接訪問該 IP 地址烹骨。

  1. 搜索操作系統(tǒng)自身的 DNS 緩存。(瀏覽器沒有找到緩存或者緩存已經(jīng)失效)
  2. 讀取本身的 HOST 文件材泄。(如果前1.2步驟都沒有找到)
  3. 瀏覽器向?qū)拵н\(yùn)營商服務(wù)器或者域名服務(wù)器發(fā)起一個(gè) DNS 解析請求沮焕。
    服務(wù)器先查看本身的緩存,若找到則返回百度首頁的 IP 地址拉宗,若沒有找到峦树,則服務(wù)器就發(fā)起一個(gè)迭代 DNS 解析的請求,如下圖:

從圖中我們可以看出域名服務(wù)器先向根域名服務(wù)器發(fā)起DNS解析請求旦事,接著迭代發(fā)起請求魁巩,直到找到所搜索的百度首頁的 IP 地址,并將它返回給瀏覽器姐浮。

  1. 拿到 IP 地址后谷遂,瀏覽器就向該 IP 所在的服務(wù)器發(fā)起 TCP 連接(即三次握手)。
  2. 連接建立起來之后卖鲤,瀏覽器就可以向服務(wù)器發(fā)起 HTTP 請求了肾扰。

這里比如訪問百度首頁,就向服務(wù)器發(fā)起 HTTP 中的 GET 請求扫尖。

  1. 服務(wù)器接受到這個(gè)請求后白对,根據(jù)路徑參數(shù),經(jīng)過后臺一些處理之后换怖,把處理后的結(jié)果返回給瀏覽器甩恼,如果是百度首頁,就可以把完整的 HTML 頁面代碼返回給瀏覽器沉颂。
  2. 瀏覽器拿到了百度首頁的完整 HTML 頁面代碼条摸,內(nèi)核和 JS 引擎就會解析和渲染這個(gè)頁面,里面的 JS铸屉,CSS钉蒲,圖片等靜態(tài)資源也通過一個(gè)個(gè) HTTP 請求進(jìn)行加載。
  3. 瀏覽器根據(jù)拿到的資源對頁面進(jìn)行渲染彻坛,最終把完整的頁面呈現(xiàn)給用戶顷啼。
  4. 如果瀏覽器沒有后續(xù)的請求踏枣,那么就會跟服務(wù)器端發(fā)起 TCP 斷開(即四次揮手)。

至此钙蒙,整個(gè)訪問過程就結(jié)束了茵瀑,這里只是簡單的概括,實(shí)際情況遠(yuǎn)比這些復(fù)雜躬厌。

HTTP 概念

超文本傳輸協(xié)議(HTTP马昨,HyperText Transfer Protocol)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。所有的WWW文件都必須遵守這個(gè)標(biāo)準(zhǔn)扛施。

舉個(gè)可能不太恰當(dāng)?shù)睦雍枧酰琓CP 就好比端與端之間溝通的橋梁,而 HTTP 就像是一個(gè)搬運(yùn)工疙渣,通過這個(gè)橋梁搬運(yùn)資源匙奴。

HTTP 特性:

  • HTTP 構(gòu)建于 TCP/IP 協(xié)議之上,默認(rèn)端口號是 80
  • HTTP 是無連接無狀態(tài)的

HTTP 分為兩個(gè)部分:請求和響應(yīng)昌阿。

HTTP 內(nèi)容

HTTP 請求:

HTTP 定義了在與服務(wù)器交互的不同方式饥脑,最常用的方法有 4 種,分別是 GET懦冰,POST,PUT谣沸, DELETE刷钢。URL 全稱為資源描述符,可以這么認(rèn)為:一個(gè) URL 地址乳附,對應(yīng)著一個(gè)網(wǎng)絡(luò)上的資源内地,而 HTTP 中的 GET,POST赋除,PUT阱缓,DELETE 就對應(yīng)著對這個(gè)資源的查詢,修改举农,增添荆针,刪除4個(gè)操作。

HTTP 請求由 3 個(gè)部分構(gòu)成颁糟,分別是:狀態(tài)行航背,請求頭(Request Header),請求正文棱貌。

狀態(tài)行由協(xié)議玖媚,狀態(tài)描述等構(gòu)成,各元素之間以空格分隔婚脱。

請求頭提供一些參數(shù)比如:Cookie今魔,用戶代理信息勺像,主機(jī)名等等。

請求正文就放一些發(fā)送的數(shù)據(jù)错森,一般 GET 請求會將參數(shù)放在 URL 中吟宦,也就是在請求頭中而請求正文一般為空,而 POST 請求將參數(shù)放在請求正文中问词。

  • GET 一般用于信息獲取督函,比如剛才我們?yōu)g覽百度首頁,其使用的就是GET方法激挪。

GET請求報(bào)文實(shí)例:

GET 請求報(bào)文

GET 請求一般不會產(chǎn)生副作用辰狡,它僅僅只是獲取資源信息,就像數(shù)據(jù)庫查詢一樣垄分,不會修改宛篇、增加數(shù)據(jù),不會影響資源的狀態(tài)薄湿,并且對同一個(gè) URL 的多次GET請求應(yīng)該返回相同的結(jié)果叫倍。

  • POST 請求表示可能會修改服務(wù)器上的資源。
POST 請求報(bào)文

注:

  1. GET 和 POST 請求參數(shù)位置不同,從上面兩個(gè)請求報(bào)文可以看出侠鳄,GET 請求對應(yīng)的參數(shù)放在 URL 中灵临,而 POST 請求對應(yīng)的參數(shù)放在 HTTP 請求主體中。
  2. GET 可提交的數(shù)據(jù)量受 URL 長度的限制蚕泽,而 POST 的數(shù)據(jù)量則沒有限制。
  3. 處于安全考慮桥嗤,在一些涉及安全的請求比如:登錄請求需要用 POST 提交表單须妻,而GET 請求一般用來獲取靜態(tài)資源。

HTTP 響應(yīng):

HTTP 響應(yīng)是服務(wù)器在客戶端發(fā)送 HTTP 請求后經(jīng)過一些處理而做出的響應(yīng)泛领,HTTP 響應(yīng)和 HTTP 請求相似荒吏,也是由三個(gè)部分構(gòu)成。分別是:狀態(tài)行渊鞋,響應(yīng)頭(Response Header)绰更,響應(yīng)正文。

HTTP 響應(yīng)中包含一個(gè)狀態(tài)碼篓像,用來表示服務(wù)器對客戶端響應(yīng)的結(jié)果动知。

狀態(tài)碼一般由3位構(gòu)成:

  • 1xx : 表示請求已經(jīng)接受了,繼續(xù)處理员辩。
  • 2xx : 表示請求已經(jīng)處理掉了盒粮。
  • 3xx : 重定向。
  • 4xx : 一般表示客戶端有錯(cuò)誤奠滑,請求無法實(shí)現(xiàn)丹皱。
  • 5xx : 一般為服務(wù)器端的錯(cuò)誤妒穴。

比較常用的狀態(tài)碼:

  • 200 OK 客戶端請求成功。
  • 301 Moved Permanently 請求永久重定向摊崭。
  • 302 Moved Temporarily 請求臨時(shí)重定向讼油。
  • 304 Not Modified 文件未修改,可以直接使用緩存的文件呢簸。
  • 400 Bad Request 由于客戶端請求有語法錯(cuò)誤矮台,不能被服務(wù)器所理解。
  • 401 Unauthonzed 請求未經(jīng)授權(quán)根时,無法訪問瘦赫。
  • 403 Forbidden 服務(wù)器收到請求,但是拒絕提供服務(wù)蛤迎。服務(wù)器通常會在響應(yīng)正文中給出不提供服務(wù)的原因确虱。
  • 404 Not Found 請求的資源不存在,比如輸入了錯(cuò)誤的URL替裆。
  • 500 Internal Server Error 服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤校辩,導(dǎo)致無法完成客戶端的請求。
  • 503 Service Unavailable 服務(wù)器當(dāng)前不能夠處理客戶端的請求辆童,在一段時(shí)間之后宜咒,服務(wù)器可能會恢復(fù)正常。

下面是一個(gè) HTTP 響應(yīng)的例子:

HTTP 響應(yīng)

知道了 HTTP 請求和響應(yīng)后把鉴,一個(gè)完整的流程一般是這樣的:

通常荧呐,由 HTTP 客戶端發(fā)起一個(gè)請求,建立一個(gè)到服務(wù)器指定端口(默認(rèn)是 80 端口)的 TCP 連接纸镊。HTTP 服務(wù)器則在那個(gè)端口監(jiān)聽客戶端發(fā)送過來的請求。一旦收到請求概疆,服務(wù)器(向客戶端)發(fā)回一個(gè)狀態(tài)行逗威,比如"HTTP/1.1 200 OK",和(響應(yīng)的)消息岔冀,消息的消息體可能是請求的文件凯旭、錯(cuò)誤消息、或者其它一些信息使套。

HTTP 使用 TCP 而不是 UDP 的原因在于(打開)一個(gè)網(wǎng)頁必須傳送很多數(shù)據(jù)罐呼,而 TCP 協(xié)議提供傳輸控制,按順序組織數(shù)據(jù)侦高,和錯(cuò)誤糾正嫉柴。

其它

了解以上那些概念后,已經(jīng)對 HTTP 協(xié)議有了大致的了解了奉呛。下面介紹一些 HTTP 實(shí)現(xiàn)中具體內(nèi)容计螺。

會話追蹤

  • 會話:客戶端向服務(wù)器端發(fā)起請求到服務(wù)端響應(yīng)客戶端請求的全過程夯尽。
  • 會話跟蹤:會話追蹤指的是服務(wù)器對用戶響應(yīng)的監(jiān)視。

為什么需要會話跟蹤:

瀏覽器與服務(wù)器之間的通信是通過 HTTP 協(xié)議進(jìn)行通信的登馒,而 HTTP 協(xié)議是”無狀態(tài)”的協(xié)議匙握,它不能保存客戶的信息,即一次響應(yīng)完成之后連接就斷開了陈轿,下一次的請求需要重新連接圈纺,這樣就需要判斷是否是同一個(gè)用戶,所以才有會話跟蹤技術(shù)來實(shí)現(xiàn)這種要求麦射。

會話跟蹤常用方法:

  • URL 重寫:URL 重寫技術(shù)就是在 URL 結(jié)尾添加一個(gè)附加數(shù)據(jù)以標(biāo)識該會話蛾娶,把會話 ID 通過 URL 的信息傳遞過去,以便在服務(wù)器進(jìn)行識別不同的用戶法褥。
  • 隱藏表單域:將會話ID添加到HTML表單元素中提交到服務(wù)器茫叭,此表單元素并不在客戶端顯示。
  • Cookie:Cookie 是 Web 服務(wù)器發(fā)送給客戶端的一小段信息半等,客戶端請求時(shí)可以讀取該信息發(fā)送給服務(wù)器端揍愁,進(jìn)而進(jìn)行用戶的識別,對于客戶端的每次請求杀饵,服務(wù)器都會將 Cookie 發(fā)送到客戶端莽囤,客戶端保存下來,以便下次使用切距。

客戶端可以采用兩種方式來保存這個(gè)Cookie對象朽缎,一種方式是保存在客戶端內(nèi)存中,稱為臨時(shí)Cookie谜悟,瀏覽器關(guān)閉后這個(gè)Cookie對象將消失话肖。

另外一種方式是保存在客戶機(jī)的磁盤上,稱為永久Cookie葡幸。以后客戶端只要訪問該網(wǎng)站最筒,就會將這個(gè)Cookie再次發(fā)送到服務(wù)器上,前提是這個(gè)Cookie在有效期內(nèi)蔚叨,這樣就實(shí)現(xiàn)了對客戶的跟蹤床蜘。

Cookie 是可以被禁止的,當(dāng)你打開 Chrome蔑水,在設(shè)置里面關(guān)閉 Cookie邢锯,那么你將再也無法登錄淘寶頁面。

  • Session:在服務(wù)器端會創(chuàng)建一個(gè) session 對象搀别,產(chǎn)生一個(gè) sessionID 來標(biāo)識這個(gè) session 對象丹擎,然后將這個(gè) sessionID 放入到 Cookie 中發(fā)送到客戶端,下一次訪問時(shí)领曼,sessionID 會發(fā)送到服務(wù)器鸥鹉,在服務(wù)器端進(jìn)行識別不同的用戶蛮穿。

每一個(gè)用戶都有一個(gè)不同的 session,各個(gè)用戶之間是不能共享的毁渗,是每個(gè)用戶所獨(dú)享的践磅,在 session 中可以存放信息。

Session的實(shí)現(xiàn)依賴于Cookie灸异,如果Cookie被禁用府适,那么session也將失效。

條件 GET:

HTTP 條件 GET 是 HTTP 協(xié)議為了減少不必要的帶寬浪費(fèi)肺樟,提出的一種方案檐春。

  1. HTTP 條件 GET 使用時(shí)機(jī):客戶端之前已經(jīng)訪問過某網(wǎng)站,并打算再次訪問該站點(diǎn)么伯。
  2. HTTP 條件 GET 使用的方法:客戶端向服務(wù)器發(fā)送一個(gè)包詢問是否在上一次訪問網(wǎng)站的時(shí)間后是否更改了頁面疟暖,如果服務(wù)器沒有更新,顯然不需要把整個(gè)網(wǎng)頁傳給客戶端田柔,客戶端只要使用本地緩存即可俐巴,如果服務(wù)器對照客戶端給出的時(shí)間已經(jīng)更新了客戶端請求的網(wǎng)頁,則發(fā)送這個(gè)更新了的網(wǎng)頁給用戶硬爆。

下面是一個(gè)具體的發(fā)送接受報(bào)文示例:

客戶端發(fā)送請求:

客戶端發(fā)送請求

第一次請求時(shí)欣舵,服務(wù)器端返回請求數(shù)據(jù),之后的請求缀磕,服務(wù)器根據(jù)請求中的 If-Modified-Since 字段判斷響應(yīng)文件沒有更新缘圈,如果沒有更新,服務(wù)器返回一個(gè) 304 Not Modified響應(yīng)袜蚕,告訴瀏覽器請求的資源在瀏覽器上沒有更新糟把,可以使用已緩存的上次獲取的文件。

服務(wù)器響應(yīng)請求

如果服務(wù)器端資源已經(jīng)更新的話牲剃,就返回正常的響應(yīng)糊饱。

持久連接:

我們知道 HTTP 協(xié)議采用“請求-應(yīng)答”模式,當(dāng)使用普通模式颠黎,即非 Keep-Alive 模式時(shí),每個(gè)請求/應(yīng)答客戶和服務(wù)器都要新建一個(gè)連接滞项,完成之后立即斷開連接(HTTP協(xié)議為無連接的協(xié)議)狭归;當(dāng)使用 Keep-Alive 模式(又稱持久連接、連接重用)時(shí)文判,Keep-Alive 功能使客戶端到服務(wù)器端的連接持續(xù)有效过椎,當(dāng)出現(xiàn)對服務(wù)器的后繼請求時(shí),Keep-Alive 功能避免了建立或者重新建立連接戏仓。

在 HTTP 1.0 版本中疚宇,并沒有官方的標(biāo)準(zhǔn)來規(guī)定 Keep-Alive 如何工作亡鼠,因此實(shí)際上它是被附加到 HTTP 1.0協(xié)議上,如果客戶端瀏覽器支持 Keep-Alive 敷待,那么就在HTTP請求頭中添加一個(gè)字段 Connection: Keep-Alive间涵,當(dāng)服務(wù)器收到附帶有 Connection: Keep-Alive 的請求時(shí),它也會在響應(yīng)頭中添加一個(gè)同樣的字段來使用 Keep-Alive 榜揖。這樣一來勾哩,客戶端和服務(wù)器之間的HTTP連接就會被保持,不會斷開(超過 Keep-Alive 規(guī)定的時(shí)間举哟,意外斷電等情況除外)思劳,當(dāng)客戶端發(fā)送另外一個(gè)請求時(shí),就使用這條已經(jīng)建立的連接妨猩。

在 HTTP 1.1 版本中潜叛,默認(rèn)情況下所有連接都被保持,如果加入 "Connection: close" 才關(guān)閉壶硅。目前大部分瀏覽器都使用 HTTP 1.1 協(xié)議威兜,也就是說默認(rèn)都會發(fā)起 Keep-Alive 的連接請求了,所以是否能完成一個(gè)完整的 Keep-Alive 連接就看服務(wù)器設(shè)置情況森瘪。

由于 HTTP 1.0 沒有官方的 Keep-Alive 規(guī)范牡属,并且也已經(jīng)基本被淘汰,以下討論均是針對 HTTP 1.1 標(biāo)準(zhǔn)中的 Keep-Alive 展開的扼睬。

小結(jié):

  1. 會話跟蹤和條件 GET 是有不同的逮栅,它們分別運(yùn)用于不同的場景。會話跟蹤是服務(wù)器用來表示標(biāo)識區(qū)分不同的用戶窗宇,而有條件 GET 則用戶多次訪問相同的頁面措伐,用來減少帶寬的浪費(fèi),兩者有本質(zhì)上的區(qū)別军俊。
  2. HTTP Keep-Alive 簡單說就是保持當(dāng)前的TCP連接侥加,避免了重新建立連接。
  3. HTTP 是一個(gè)無狀態(tài)無連接的協(xié)議粪躬,那么這是不是與 Keep-Alive 沖突担败?

個(gè)人認(rèn)為:Keep-Alive 與無連接的特性沖突,而對于無狀態(tài)的特性兩者并無矛盾镰官,HTTP 無狀態(tài)無連接是在 1.0 版本中就規(guī)定的提前,而 Keep-Alive 則是在 1.1 版本中才被添加入規(guī)范。

無連接的意思是限制每個(gè)連接只有一個(gè)請求的意思泳唠,在服務(wù)器處理完客戶的請求狈网,并收到客戶的反應(yīng),即斷開。通過這種方式可以節(jié)省傳輸時(shí)間拓哺。

Keep-Alive 確實(shí)破壞了這一特性勇垛,而無狀態(tài)協(xié)議則意味著每個(gè)請求都是獨(dú)立的,互不干擾的士鸥,互相沒有記憶的闲孤。所以才需要有會話跟蹤這種機(jī)制來識別用戶。

參考鏈接:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末础淤,一起剝皮案震驚了整個(gè)濱河市崭放,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸽凶,老刑警劉巖币砂,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玻侥,居然都是意外死亡决摧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門凑兰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掌桩,“玉大人,你說我怎么就攤上這事姑食〔ǖ海” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵音半,是天一觀的道長则拷。 經(jīng)常有香客問我,道長曹鸠,這世上最難降的妖魔是什么煌茬? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮彻桃,結(jié)果婚禮上坛善,老公的妹妹穿的比我還像新娘。我一直安慰自己邻眷,他們只是感情好眠屎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肆饶,像睡著了一般组力。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抖拴,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼阿宅。 笑死候衍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洒放。 我是一名探鬼主播蛉鹿,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼往湿!你這毒婦竟也來了妖异?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤领追,失蹤者是張志新(化名)和其女友劉穎他膳,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绒窑,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棕孙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了些膨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蟀俊。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖订雾,靈堂內(nèi)的尸體忽然破棺而出肢预,到底是詐尸還是另有隱情,我是刑警寧澤洼哎,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布烫映,位于F島的核電站,受9級特大地震影響谱净,放射性物質(zhì)發(fā)生泄漏窑邦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一壕探、第九天 我趴在偏房一處隱蔽的房頂上張望冈钦。 院中可真熱鬧,春花似錦李请、人聲如沸瞧筛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽较幌。三九已至,卻和暖如春白翻,著一層夾襖步出監(jiān)牢的瞬間乍炉,已是汗流浹背绢片。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岛琼,地道東北人底循。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像槐瑞,于是被迫代替她去往敵國和親熙涤。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容