拋去瀏覽器的內部基礎機制和返回頁面的渲染之類的不說,當從網絡的角度來看其中的基本步驟:
1.瀏覽器查看緩存,如果請求的內容在緩存之中並且是在存活時限之內就會執行第10步
2.瀏覽器會向操作系統詢問該請求對應的IP地址
操作系統開始尋找域名對應的IP地址並最終返回給瀏覽器。系統查找IP地址,一般先查看瀏覽器的緩存,如果緩存中沒有請求域名對應的IP地址,就會去查找在本地的host文件中是否存在對應的IP,如果還找不到就會詢問DNS服務器。
DNS解析過程
3.瀏覽器開始建立與服務器的TCP連接
HTTP的底層是依靠TCP來通信的,所以簡單介紹一些TCP/IP協議:
TCP/IP 協議族里重要的一點就是分層。TCP/IP 協議族按層次分別分為以下 4 層:應用層、傳輸層、網絡層和數據鏈路層。
應用層:應用層決定了向用戶提供應用服務時通信的活動(如FTP,DNS,HTTP)。
傳輸層:傳輸層對上層應用層,提供處於網絡連接中的兩台計算機之間的數據傳輸。
在傳輸層有兩個性質不同的協議:TCP(Transmission Control Protocol,傳輸控制協議和 UDP(User Data Protocol,用戶數據報協議)。
網絡層:網絡層用來處理在網絡上流動的數據包。數據包是網絡傳輸的最小數據單位。該層規定了通過怎樣的路徑(所謂的傳輸路線)到達對方計算機,並把數據包傳送給對方。
鏈路層:用來處理連接網絡的硬件部分。包括控制操作系統、硬件的設備驅動NIC(Network Interface Card,網絡適配器,即網卡),及光纖等物理可見部分(還包括連接器等一切傳輸媒介)。硬件上的范疇均在鏈路層的作用范圍之內。
下圖是TCP/IP的信息流:
TCP/IP信息流
HTTP通信是基於TCP/IP協議的,因此在通信之前會與目標服務器建立TCP連接,TCP為了保證可靠性,會進行三次握手,確認雙方正式建立連接。
第一次握手:建立連接。客戶端發送連接請求報文段,將SYN位置為1,Sequence Number為x;然后,客戶端進入SYN_SEND狀態,等待服務器的確認;
第二次握手:服務器收到SYN報文段。服務器收到客戶端的SYN報文段,需要對這個SYN報文段進行確認,設置Acknowledgment Number為x+1(Sequence Number+1);同時,自己自己還要發送SYN請求信息,將SYN位置為1,Sequence Number為y;服務器端將上述所有信息放到一個報文段(即SYN+ACK報文段)中,一並發送給客戶端,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK報文段。然后將Acknowledgment Number設置為y+1,向服務器發送ACK報文段,這個報文段發送完畢以后,客戶端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手。
三次握手
三次握手
4.瀏覽器通過TCP連接發送HTTP請求
TCP連接建立后就可以開始發送HTTP報文了,由於底層通信使用了TCP/IP協議,因此HTTP報文在客戶端會被層層包裝添加TCP/IP協議中每一層的首部信息,直到被包裝后的請求內容到達服務器端。服務器端接收到信息后又會逆向層層解包直到得到原本的HTTP報文。
HTTP通過TCP/IP信息流
5.服務器接收到請求后對請求做出處理,然后返回HTTP response。
一般來說,服務器接收到請求會根據請求的路徑尋找一個可以處理該請求的程序。用MVC框架來解釋就是:根據請求的路徑找到對應處理請求的controller,之后控制器會調用業務邏輯處理請求,然后返回一個Model,之后通過視圖解析器的包裝最終變成一個response然后通過已經建立好的TCP連接以同樣的傳輸方式返回給瀏覽器。
6.瀏覽器接收到HTTP響應,選擇關閉TCP連接,或者繼續維持等待下一次請求的發生如果選擇關閉連接,會進行TCP的四次揮手
第一次揮手:主機1(可以使客戶端,也可以是服務器端),設置Sequence Number,向主機2發送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有數據要發送給主機2了;
第二次揮手:主機2收到了主機1發送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number為Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我“同意”你的關閉請求;
第三次揮手:主機2向主機1發送FIN報文段,請求關閉連接,同時主機2進入LAST_ACK狀態;
第四次揮手:主機1收到主機2發送的FIN報文段,向主機2發送ACK報文段,然后主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段以后,就關閉連接;此時,主機1等待2MSL后依然沒有收到回復,則證明Server端已正常關閉,那好,主機1也可以關閉連接了。
四次揮手
7.瀏覽器檢查收到的響應的狀態碼
瀏覽器檢查響應是否是一個重定向響應或者是一個需要特殊處理的響應(3xx的狀態碼),或者是需要重新認證(401狀態碼),或者錯誤(4xx和5xx狀態碼)等;瀏覽器會和正常的響應(2xx)相區別並作出不同的應對。
HTTP狀態碼
8.如果緩存是可用的,響應會被放入緩存
9.瀏覽器對響應進行解碼(通常使用gzip)
10.瀏覽器真正決定如何處理這個響應
判斷響應是什么文件,比如是HTML頁面或者是圖片,又或者是聲音文件。如果是頁面,瀏覽器會渲染並呈現給用戶,又或者是提供認證或者是下載的窗口等,取決於瀏覽器收到了什么類型的響應。
下面的兩個圖可以輔助理解這個過程:
HTTP工作流程
各個協議之間的關系
如果請求使用了HTTPS那么流程會有什么不同?
HTTPS實際上是為了保證HTTP的安全性而在HTTP的基礎上加入加密處理和認證等機制。通常,HTTP直接和TCP通信。當使用SSL時,則演變成先和SSL通信,再由SSL和TCP通信了。簡言之,所謂HTTPS,其實就是身披SSL協議這層外殼HTTP。
HTTP和HTTPS
實際上不管怎么稱呼,實現安全性的一種通用的措施就是對通信內容進行加密。那么最常用的兩種加密方式無非是對稱加密和非對稱加密。對稱加密即雙方持有相同的密鑰進行加密和解密,但是在網絡環境下如何傳輸密鑰就成了問題。於是出現了非對稱加密通信雙方持有對方的公鑰和自己的私鑰,使用公鑰加密,私鑰解密。很明顯對稱加密的效率要比非對稱加密高,因此HTTPS使用了混合加密的方式。用非對稱加密傳輸共享密鑰,然后用共享密鑰進行對稱加密傳輸。
因此HTTPS的通信過程大概如下圖所示
HTTPS通信過程
步驟 1:客戶端通過發送Client Hello報文開始SSL通信。報文中包含客戶端支持的SSL的指定版本、加密組件(Cipher Suite)列表(所使用的加密算法及密鑰長度等)。
步驟 2: 服務器可進行SSL通信時,會以Server Hello報文作為應答。和客戶端一樣,在報文中包含SSL版本以及加密組件。服務器的加密組件內容是從接收到的客戶端加密組件內篩選出來的。
步驟 3: 之后服務器發送Certificate報文。報文中包含公開密鑰證書。
步驟 4: 最后服務器發送Server Hello Done報文通知客戶端,最初階段的 SSL 握手協商部分結束。
步驟 5: SSL 第一次握手結束之后,客戶端以Client Key Exchange報文作為回應。報文中包含通信加密中使用的一種被稱為Pre-mastersecret的隨機密碼串。該報文已用步驟3中的公開密鑰進行加密。
步驟 6: 接着客戶端繼續發送Change Cipher Spec報文。該報文會提示服務器,在此報文之后的通信會采用Pre-master secret密鑰加密。
步驟 7: 客戶端發送Finished報文。該報文包含連接至今全部報文的整體校驗值。這次握手協商是否能夠成功,要以服務器是否能夠正確解密該報文作為判定標准。
步驟 8: 服務器同樣發送Change Cipher Spec報文。
步驟 9: 服務器同樣發送Finished報文。
步驟 10: 服務器和客戶端的Finished報文交換完畢之后,SSL連接就算建立完成。當然,通信會受到SSL的保護。從此處開始進行應用層協議的通信,即發送HTTP請求。
步驟 11: 應用層協議通信,即發送HTTP響應。
步驟 12: 最后由客戶端斷開連接。斷開連接時,發送close_notify報文。上圖做了一些省略,這步之后再發送TCP FIN報文來關閉與TCP的通信。
下面的圖對上面的流程做了一個補充:
HTTPS通信協商
也就是流程中從第1步到第9步都是通過協商確定對稱加密的過程,第九步結束之后,通信雙方都確定了使用對稱加密,確認雙方使用了同一個共享的密鑰,之后的通信就是在對稱加密基礎上的通信了。
參考:
圖解HTTP