天天看點

一次完整的http請求全過程(知識體系版)超長文預警

最差的面試體驗

面試官評價:除了學曆,和教育訓練班出來的沒差別。

确實,很多東西我隻是會用。面完回來,我發現我确實連一個完整的http請求如何發送都不明白。

失敗并不可怕。但是一定得把失敗的悲痛化成力量!

我覺得需要把掌握的知識串成一套完整的知識體系。

超長文預警

一次完整的http請求的全過程

域名解析------>tcp建立三次握手過程------>
    發送http請求------>伺服器傳回html------>
    浏覽器根據html建構dom樹,cssom樹,加載資源------>
呈現給使用者
           

簡而言之就是這麼一句話,也是很多同學會背的一句話。但是如果把這幾個階段拆出來大做文章。那也得需要不少的篇幅。

什麼是http

維基百科上的http

超文本傳輸協定,是一個用戶端和服務端之間請求和應答的标準。是一個基于TCP/IP協定、屬于應用層的面向對象的協定。用戶端發起一個HTTP請求到伺服器上指定端口(預設端口是80)。請求和響應消息的頭以ascll碼的形式給出。

通俗來說:http是網絡通信必須遵守的規則,是一個基于請求和響應,無狀态的,基于TCP/IP的應用層的協定。

請求和響應:用戶端發送請求,伺服器端傳回響應。

無狀态的:協定對于事務處理沒有記憶能力,用戶端第一次與伺服器建立連接配接發送請求時需要進行一系列的安全認證比對等,是以增加頁面等待時間,當用戶端向伺服器端發送請求,伺服器端響應完畢後,兩者斷開連接配接,也不儲存連接配接狀态,下一次用戶端向同樣的伺服器發送請求時,由于他們之前已經遺忘了彼此,是以需要重建立立連接配接。

應用層: Http是屬于應用層的協定,配合TCP/IP使用。

TCP/IP: Http使用TCP作為它的支撐運輸協定。HTTP客戶機發起一個與伺服器的TCP連接配接,一旦連接配接建立,浏覽器(客戶機)和伺服器程序就可以通過套接字接口通路TCP。

一、域名解析

定義,将域名解析成對應的IP位址。

刁民問:為什麼要用域名?不直接使用ip位址?

思考:如果我們要通路百度官網。你覺得是在浏覽器中輸入www.baidu.com友善,還是輸入14.215.177.39友善。再者,伺服器端有可能更換ip位址,但是域名的A記錄解析到了ip位址。更不更換ip位址都和我們沒關系。

答:使用域名更加友善使用者記憶。并且服務端如果更換主機,ip位址發生了變化對使用者沒有影響。不使用域名也無法使用CDN分發網絡,必須從網站拿資源,降低了網站的通路速度。

DNS域名解析系統(Domain name system)

為什麼要進行DNS域名解析?

網絡通信都是基于tcp/ip的,tcp/ip是基于ip協定的。而ip協定隻能識别ip位址。是以需要将指定的域名通過DNS解析為ip位址。

dns域名的工作過程?

當DNS客戶機需要使用到名稱時,它會查詢本地DNS伺服器來解析該名稱。每條查詢消息包括三個資訊

1、指定的查詢域名

2、指定的查詢類型

3、DNS指定的查詢類别

DNS域名的兩種查詢方式

遞歸查詢和疊代查詢。

兩者的查詢順序都是一樣的。客戶機本地緩存--->本地DNS伺服器--->根域名伺服器--->頂級域名伺服器--->域名提供商

遞歸查詢是将查詢結果按照查詢過程一層層傳回回來,而疊代查詢查詢到了之後可以直接傳回。

DNS域名解析的請求和響應資料報均經過UDP的53端口來發送。

為什麼通過udp而不通過可靠的tcp?

udp隻需要發送兩個封包,請求包,響應包。tcp需要握手三個包,請求包,響應包,揮手四個包。一共九個包相比較之下udp的效率更高。

二、建立tcp連接配接

講到TCP,不得不提到的是

TCP和UDP的差別

TCP基于連接配接,UDP不基于連接配接

TCP面向位元組流,UDP面向封包

TCP隻能1對1,UDP可以一對多

TCP首部較大為20個位元組,UDP首部隻有8個位元組

TCP提供可靠的連接配接,UDP不可靠

為什麼TCP可靠?

首先分析TCP封包格式

16位源端口 16位目标端口
32位序号
32位确認序号
4位資料偏移 6位保留位 URG ack psh rst syn fin 16位視窗大小
校驗和 緊急指針
選項
資料

源端口号:源端口和IP位址的作用是辨別封包的傳回位址。

目标端口号:指接收方計算機應用程式接口。

序号:本封包資料組發送的第一個位元組的序号

确認号:指明下一個期待收到的位元組序号,同時也表明了該序号之前的資料已經準确無誤的收到。

資料偏移:有4位,由于封包格式中有選項這個概念,是以TCP報頭長度是不确定的。資料偏移實際上是指TCP報頭的資料部分在報頭的偏移量。4位二進制能表示的最大十進制數字是1111也就是15。又因為資料偏移使用的機關是32位字,是以封包最大長度為15*32/8 = 60位元組。

6位保留位:為将來可能出現的功能保留的位置。

URG:緊急指針标志位,URG為1時緊急指針才有效。

ACK:為1時,标志位才有效。

PSH:push,指接收方接收到這個封包字段時,不放入緩存區,直接傳遞給應用程式

RST:指發生了難以預計的錯誤需要重置連接配接

SYN:同步序号,用于建立連接配接過程

FIN:用于斷開連接配接的标志号。

視窗:滑動視窗大小,用來告訴發送端接受端的緩存大小是多少,進而控制資料傳輸的速率,進而達到流量控制的目的。

校驗和:由發送端計算和存儲。由接收端校驗。

緊急指針:URG為1時緊急指針有效,是一個正的偏移量。和序号相加為緊急資料最後一個位元組的序号。

好了,TCP封包格式分析完了,現在回到我們的問題,為什麼TCP的連接配接是可靠的。

确認和重傳機制:三次握手同步雙方的序号,确認号,視窗大小,是确認重傳和流量控制的基礎。

在傳輸過程中,如果校驗和校驗失敗,丢包或者延時,發送端會立馬重傳。

資料排序:有專門的序号字段,可以提供資料re-order。

流量控制:視窗字段可以指明雙方最大的資料傳輸和接受量

擁塞控制:由四個核心算法實作:慢啟動,擁塞避免,快速重傳,快速恢複。

以上就是TCP比UDP更加可靠的原因。

tcp比udp可靠,那麼udp可以應用在哪些地方?

tcp(傳輸控制協定),提供的是可靠的運輸,基于連接配接同時也說明需要的時間更長。應用于需要可靠性較高的場所。http請求,檔案傳輸等等。

udp不基于連接配接。速度更快,應用于網絡通訊速度較快的場景。比如語音電話、視訊、直播等等。

TCP講完了,講到http請求封包和響應封包

http請求封包格式:請求行,請求頭,請求體

請求行:包括四個部分 請求方法、請求位址、空行、協定版本、

說到請求方法,http常用的幾種請求方法也是需要知道的。get、post、put、delete、option、head等等。

說到get和post方法,兩者有什麼差別?

get post
作用 一般用于請求資料或者資源 一般用于送出或者修改資料
使用緩存 可以使用緩存 不可以使用緩存
傳遞參數 通過url傳遞參數,有長度限制,隻能傳遞字元串 通過request body傳遞參數,可以傳遞各種類型的參數
安全性 不安全(參數明文暴露在url位址中) 較安全
資料包 1個 2個

為什麼會産生兩個資料包?

發送get請求時,将http header和data一并發送,伺服器傳回狀态碼200(ok)

發送post請求時,先發送http header,伺服器傳回100(continue),然後再發送data(伺服器傳回200(ok))

請求頭:請求封包的一些附加資訊。(需要記住一些http常見請求頭)

一次完整的http請求全過程(知識體系版)超長文預警

請求頭的最後有一行空行表示請求頭的結束,這一很重要,必不可少。這是判斷請求頭是否結束的條件。

請求體:英文(request body)熟不熟悉?沒錯(看看get和post差別表),post請求就是靠這個來傳遞參數,而get方法就沒有這個請求體;

帶上一個簡單的post請求執行個體。

POST  /index.php HTTP/1.1    請求行Host: localhost                 接受請求的ip位址,也可以是域名。User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 發送請求的應用程式名稱 這裡根據Mozilla核心和Firefox不難判斷是火狐浏覽器發送的請求。Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8Accept-Language: zh-cn,zh;q=0.5  可接受的語言格式Accept-Encoding: gzip, deflate   可接受的壓縮格式Connection: keep-alive           連接配接屬性Referer: http://localhost/Content-Length:25Content-Type:application/x-www-form-urlencoded  空行username=aa&password=1234  請求資料
           

http響應封包格式:

同樣的,http響應封包也包括了四個部分:響應行、響應頭、空行、響應體。

響應行:包括協定版本、狀态碼

響應頭:響應封包的一些附加資訊(同樣的,也需要記住一些常見的響應頭)

一次完整的http請求全過程(知識體系版)超長文預警

響應體:傳回資料

一個執行個體

HTTP/1.1200 OK  狀态行Date: Sun, 17 Mar 201308:12:54 GMT  響應頭部Server: Apache/2.2.8 (Win32) PHP/5.2.5    伺服器應用程式是apacheX-Powered-By: PHP/5.2.5Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/Expires: Thu, 19 Nov 198108:52:00 GMT      過期時間Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0Pragma: no-cache Content-Length: 4393   正文長度Keep-Alive: timeout=5, max=100Connection: Keep-AliveContent-Type: text/html; charset=utf-8   傳回的正文格式  空行  響應資料HTTP響應示例Hello HTTP!
           

下面到如何發送http請求

首先需要在浏覽器中輸入url位址,計算機會尋找該url對應的ip位址,首先會在緩存中查找,查找順序為浏覽器緩存---->系統緩存----->路由器緩存,如果沒找到就在本地host伺服器中查找,如果還沒找到就在本地DNS域名伺服器中查找。找到url對應的IP位址通過三次握手建立連接配接。用戶端發送一個SYN同步請求,同時用戶端進入SYN_SENT狀态,服務端接收到資料包,進入SYN_REVD狀态,同時傳回SYN同步請求和ACK确認号給用戶端,用戶端接收到ACK确認包進入esdablished就緒狀态,伺服器端接收到ACK确認包同時進入esdablished就緒狀态。用戶端根據請求頭中的cache-control字段和expires字段判斷有沒有命中協商緩存,如果沒有命中,則發送一個http請求給服務端,服務端根據if-modified、last-modified、etag字段判斷有沒有命中強緩存。沒有命中則從伺服器擷取資料,根據伺服器端傳回的html建構dom樹和cssom樹,合并成渲染樹呈現在浏覽器頁面中,最後加載所需的資源。會話結束通過四次揮手斷開連接配接。請求方發送一個FIN請求釋放連接配接,同時進入FIN_wait1狀态,接收方收到FIN進入CLOSE_WAIT狀态,表示已經接收到發送方的關閉連接配接請求,等到接受方的資料發送完畢也要關閉連接配接時,發送一個FIN給發送方,同時進入CLOSE_WAIT狀态,發送方接受到FIN包,傳回ACK給接收方同時進入TIME_WAIT狀态。接收方收到ACK确認号後進入closed狀态,發送方也進入closed狀态。

三次握手圖

一次完整的http請求全過程(知識體系版)超長文預警
一次完整的http請求全過程(知識體系版)超長文預警

為什麼要三次握手?

答:為了防止已經失效的連接配接請求又傳送到了服務端。

如何了解已經失效的連接配接請求。如果兩次握手建立連接配接,發送第一個連接配接時,因為網絡或其他原因導緻請求沒有發送到服務端,

進而用戶端發送第二個連接配接請求,建立連接配接。并且成功與服務端通信,這時服務端收到了第一次發送的連接配接請求,并且又建立了連接配接,但是這次連接配接并不會發送資料而造成不必要的資源消耗。

四次揮手圖

一次完整的http請求全過程(知識體系版)超長文預警

刁民問:為什麼要四次不是兩次?

因為關閉請求方請求關閉隻代表沒有資料需要傳輸,但是不能表示接收端的資料傳輸已經完成了。是以需要四次握手才能完全确定雙方的資料已經傳輸完成。

刁民會問:關閉請求方進入的time_wait狀态的意義?

答:確定接收方收到了最後的ACK确認号,如果發送方直接進入CLOSED狀态,而接收方沒有收到ACK确認号,那麼接收方就會一直發送FIN給關閉請求方。

說了http就想說一下http2.0

允許多路複用,在此之前一個連接配接對應着一個請求,多路複用允許一次連接配接帶有多個請求

二進制分幀,采用新的二進制編碼格式将資料分成更小的資料幀

首部壓縮,采用了新的HPACK(首部壓縮算法),減少了header的大小。

伺服器端推送,伺服器端主動向用戶端推送資料。

說了http就要說https

http的ssl加密是在傳輸層實作的。

https的安全性更高,端口為443,需要ca證書,在搜尋引擎中的排名更高。

https的通信過程。

用戶端發送一個https請求,要求建立一個https連結,伺服器将網站的ca證書傳回給用戶端,雙方根據安全等級建立會話密鑰,伺服器端根據公鑰加密會話密鑰,用戶端根據私鑰解密會話密鑰完成通信過程。

從TCP/IP協定模型的角度來了解HTTP請求和響應如何傳遞的。

知乎大牛分享

一次完整的http請求全過程(知識體系版)超長文預警

封包到達接收端由低向上的過程叫做資料分用。

tcp/ip結構

一次完整的http請求全過程(知識體系版)超長文預警

七層模型各層作用及協定

一次完整的http請求全過程(知識體系版)超長文預警

從整體架構上來說tcp/ip可以分成(由底向上)鍊路層、網絡層、傳輸層、應用層。進而又可以細分成osi七層網絡模型(由下至上)實體層、資料鍊路層、網絡層、傳輸層、會話層、表示層、應用層。tcp/ip模型的建立者把osi模型中作用差不多的幾層合并起來就成了tcp/ip模型。配合上圖食用更加。

一個http請求在tcp/ip模型中完整的過程

一次完整的http請求全過程(知識體系版)超長文預警

http請求從應用層進入傳輸層,加上tcp首部,添加源和目的端口,通過tcp封裝成資料包。

進入到網絡層, 為資料包選擇路由 相關裝置:路由器

進入資料鍊路層 傳輸有位址的幀以及錯誤檢測 相關裝置:網橋、交換機

實體層 轉換成二進制資料在實體媒體上流通 相關裝置:中繼器、集線器。

傳輸層經過tcp三次握手。建立了端對端的接口。網絡層為資料包配置設定路由。鍊路層:傳輸有位址的幀以及錯誤檢測功能。

實體層将資料以二級制形式在實體媒體上流通。

最後補充一個資料鍊路層的ARP協定。

位址解析協定:完成ip位址到實體位址的映射。

為什麼要完成ip位址到實體位址的映射。

因為以太網協定規定,一台主機要與另一台主機通信,必須要知道目标主機的實體位址。tcp/ip模型中的傳輸層和網絡層隻關心目标主機的ip位址。

每一台主機都會在自己的緩存區中建立一個ARP映射表,裡面記錄着ip位址到MAC位址的映射關系,當客戶機需要發送資料時,先檢測ARP快取記錄中有沒有對應的MAC位址,如果有則直接發送,如果沒有,則向該網段所有主機發送ARP資料包,裡面含有客戶主機IP位址、客戶主機MAC位址和目标主機的MAC位址,網段的其他主機收到ARP資料包後檢查本地ip位址是否和ARP資料包中的IP位址相對應。如果不對應則直接忽略,如果對應,将客戶主機的IP位址和MAC位址寫入自己的ARP快取記錄中,然後将自己的MAC位址寫入ARP請求包中作為ARP響應包傳回。客戶主機收到響應包将MAC位址寫入ARP快取記錄中。

廣播發送請求,單點傳播傳回響應。

繼續閱讀