https://juejin.im/post/5e57d5b7f265da57133b2af9html
前言
在Web相關的問題中,從輸入URL到整個頁面加載展現到用戶面前這個問題是繞不開的,它主要涉及到網絡請求與客戶端渲染兩個步驟數據庫
- 網絡請求
- DNS解析
- TCP鏈接創建
- SSL/TLS隧道創建(HTTPS)
- 發送HTTP請求
- 返回HTTP報文
- 斷開SSL/TLS隧道
- 關閉TCP鏈接
- 客戶端渲染
本文主要介紹一下其中的網絡請求部分。瀏覽器
DNS解析
相比較於IP地址,以字符串來表示的域名更加符合人類的記憶習慣,所以用戶一般使用域名來訪問資源,而非IP地址。DNS提供域名與IP的映射服務,解析用戶輸入的域名爲真實IP地址進行訪問。緩存
解析流程
- 首先瀏覽器會查詢自身的DNS緩存,此處緩存時間較短,Chrome只有1分鐘。
- 若是瀏覽器的緩存裏沒有找到的話,則搜索系統自身的DNS緩存。
- 瀏覽器若是在上述緩存裏沒有找到對應的條目,則查找本地Host文件,若是在Host文件中查找到對應的IP的話,則使用這個IP。
- 若是在上一步未命中,則向本地DNS服務器發起請求,查詢域名對應的IP地址。請求到達服務器後,DNS服務器會首先查詢緩存,若是命中,則返回IP地址
- 若是沒有找到的話,本地DNS服務器會以遞歸查詢的方式依次向根域名服務器、頂級域名服務器、權威域名服務器發起查詢請求,直到獲取到IP地址
- 本地DNS服務器會將IP地址返回給瀏覽器並存入緩存,方便下次查詢。
查詢流程

性能優化
DNS prefetch:在代碼中,常常將一些靜態資源放在CDN中,每一個CDN地址都要去作下DNS解析,這個會浪費時間,能夠經過預先進行DNS解析,而後在請求的時候,DNS已經解析完成就不用等待了。安全
<!--在head標籤中,放在前面--> <link rel="dns-prefetch" href="//test.com"> 複製代碼
TCP鏈接創建
TCP協議位於傳輸層,負責提供可靠的字節流服務。性能優化
字節流服務:爲了方便傳輸,將大塊數據分割成以報文段爲單位的數據包進行管理。服務器
可靠的傳輸服務:將數據準確可靠地傳輸給對方網絡
爲了確保數據傳輸服務的可靠性,TCP協議採用了三次握手策略:post
- 發送端首先發送一個帶有SYN標誌的數據包給接收端
- 接收端收到後,回傳一個帶有SYN/ACK標誌的數據包傳達確認信息
- 發送端再次回傳一個帶有ACK標誌的數據包,握手結束

若是上述過程當中某個階段中斷,則TCP協議會再次以相同的次序進行握手操做創建鏈接性能
三步握手的目的是讓兩方都確認對方可以發送接收數據:
- 發送端發出,接收端接收,接收端知道發送端能發送數據
- 接收端發出,發送端接收,發送端知道接收端能發送及接收數據
- 發送端發出,接收端接收,接收端知道發送端能接收數據
SSL/TLS隧道創建(HTTPS)
說到SSL/TLS須要首先介紹下HTTPS,HTTPS是加上了加密處理、認證機制以及完整性保護的HTTP,它並不是是應用層的一種新協議,而是將HTTP通訊接口部分使用SSL/TLS協議代替。一般,HTTP會直接和TCP進行通訊,而加上這部分處理後,則演變爲先和SSL/TLS通訊,再由SSL/TLS和TCP進行通訊了,至關於加了一層SSL/TLS外殼的HTTP。
SSL協議,是一種安全傳輸協議,最初是由 Netscape 在1996年發佈,因爲一些安全的緣由SSL v1.0和SSL v2.0都沒有公開,直到1996年的SSL v3.0。TLS是SSL v3.0的升級版,目前市面上全部的HTTPS都是用的是TLS,而不是SSL。
SSL/TLS是獨立於HTTP的協議,也能夠用於其餘應用層的協議上,具體的加密等功能本文不作深刻探討,在這裏講一下SSL/TLS隧道創建的過程(四次握手):
第一次握手
- 客戶端發送Client Hello報文開始TLS/SSL通訊。報文中包含客戶端支持的TLS/SSL的指定版本以及加密組件列表
第二次握手
- 服務端支持TLS/SSL通訊時,會返回Server Hello報文。裏面一樣包含支持的TLS/SSL的指定版本以及加密組件列表
- 服務端發送Certificate報文,報文中包含公開密鑰證書
- 服務端發送Server Hello Done報文通知客戶端,TLS/SSL初步握手協商結束
第三次握手
- 客戶端發送Client Key Exchange報文,報文中包含隨機密碼串,該報文使用第一次握手步驟3中的公開密鑰進行加密
- 客戶端繼續發送Change Cipher Spec報文,該報文負責告知後續通訊的加密密碼串方式
- 客戶端發送Finished報文,報文包含鏈接至今所有報文的總體校驗值。本次握手是否成功,要以服務器可否正確解密該報文爲判斷標準
第四次握手
- 服務端發送Change Cipher Spec報文
- 服務端發送Finished報文,SSL/TLS通訊隧道創建。後續開始發送HTTP請求

發送HTTP請求
HTTP協議屬於TCP/IP族協議,用於主機之間的網絡通訊。
緩存機制
首次請求
- HTTP首次發起請求時,會先由瀏覽器查看是否有緩存數據
- 在確認無緩存數據後向服務器發起請求
- 服務器會返回數據以及緩存規則,瀏覽器在接收後存儲緩存的數據以及相應的緩存規則
緩存機制下的請求
HTTP的緩存主要分爲兩種:
- 強緩存:請求的資源在緩存中未過時時,不與服務器進行交互,直接使用緩存中的數據
- 協商緩存:當強緩存過時未命中或者
Cache-Control
中有must-revalidate
標識表示每次必須驗證資源狀態時,使用協商緩存去處理緩存文件。從緩存數據庫中取出緩存的標識,向服務器發送請求驗證請求的數據是否更新,若是已經更新則返回新的數據,若是未更新則使用緩存中的數據
總體流程

協議層傳輸過程
利用TCP/IP協議族進行網絡通訊時,會經過分層順序與對方進行通訊。發送端從應用層往下走,接收端則往應用層往上走。
- 首先做爲發送端的客戶端在應用層(HTTP協議)發出HTTP請求,獲取 Web 頁面
- 接着,爲了傳輸方便,在傳輸層(TCP 協議)把從應用層處收到的數據(HTTP 請求報文)進行分割,並在各個報文上打上標記序號及端口號後轉發給網絡層。
- 在網絡層(IP 協議),增長做爲通訊目的地的 MAC 地址後轉發給鏈路層。這樣一來,發往網絡的通訊請求就準備齊全了
- 接收端的服務器在鏈路層接收到數據,按序往上層發送,一直到應用層。當傳輸到應用層,才能算真正接收到由客戶端發送過來的 HTTP 請求。

返回HTTP報文
返回狀態碼標識請求結果
- 2XX:請求被正常處理
- 3XX:瀏覽器須要執行某些特殊的處理以正確處理請求
- 4XX:客戶端發生錯誤,請求未能成功
- 5XX:服務器端發生錯誤,請求未能成功
斷開SSL/TLS隧道
SSL/TLS隧道的斷開由客戶端發起,經過發送close_notify報文斷開
關閉TCP鏈接
在關閉鏈接時,TCP通訊雙方一共須要操做四次,稱爲四次揮手:
- 客戶端向服務端發送FIN標記的報文
- 服務端收到客戶端發送的報文後,發送一個包含確認序號ACK的報文
- 服務端向客戶端發送FIN標記報文
- 客戶端在收到FIN標記報文後,會向服務端發送確認序號ACK報文,而後通過兩個MSL時長後斷開鏈接
MSL(Maximum Segment Lifetime):最大報文生存時間,指報文發送和接收的最長時間

第二次揮手時,服務端可能還有數據報文須要發送,所以會先發送ACK報文告知客戶端已知悉要斷開請求,在處理完數據報文後會發送FIN報文給客戶端,這樣就保證了數據通訊的正常可靠性。