瀏覽器輸入URL全過程.md
瀏覽器輸入URL全過程
1 DNS域名解析
當我們在瀏覽器輸入如同www.baidu.com的時候,其實這些網站的名字都是為了簡化人們的記憶來命名的,計算機其實並不認識個東西,瀏覽器只認識IP地址,所以當輸入域名地址時,瀏覽器首先去本地host檔案,檢查該檔案中是否存在相應的域名、IP對應關係,如果有則向這個IP傳送請求,如果沒有再去DNS伺服器中找IP。
2 建立TCP連結
通過DNS域名解析後終於拿到了伺服器的IP地址,下一步就是連線伺服器。對於客戶端與伺服器的連線,當然指的是TCP的三次握手了。
基礎介紹
- SYN(SYNchronization):同步序號,用來建立連線。 SYN標誌位和ACK標誌位搭配使用,當SYN=1,ACK=0,表示連線請求;當SYN=1,ACK=1,表示連線被響應的時候;這個標誌的資料包經常被用來進行埠掃描。
- ACK(ACKnowledgment):確認號,用於確認連線是否有效。 僅當ACK=1時確認號欄位有效,當ACK=0時是無效的。TCP規定在連線建立後所有傳送的報文段都必須把ACK置為1。
- ACKNum(Acknowledgment Number):所期望收到的下一個序列號。 32位確認序列號包含傳送確認的一端所期望收到的下一個序號,因此,確認序號應當是上次已成功收到資料位元組序號加1。不過,只有當標誌位中的ACK標誌(下面介紹)為1時該確認序列號的欄位才有效。主要用來解決不丟包的問題;
- seq(Sequence Number):序列號。
- FIN(finish):表示終結連線。 當 FIN = 1 時,表明此報文段的傳送方的資料已經發送完畢,並要求釋放連線。
三次握手過程:
- 第一次握手(SYN=1,ACK=0,seq=x) 客戶端傳送一個TCP的資料包(SYN=1,ACK=0)指明客戶端打算連線伺服器的埠,以及初始序號 X,儲存在包頭的序列號(Sequence Number)欄位裡。
- 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1)
伺服器發回確認包(ACK)應答。即 SYN 標誌位和 ACK 標誌位均為1。伺服器端選擇自己 seq序列號,放到 Seq 域裡,同時將確認序號(ACKNum)設定為客戶的 seq加1,即X+1。 傳送完畢後,伺服器端進入
SYN_RCVD
狀態。 - 第三次握手(ACK=1,ACKnum=y+1)
客戶端再次傳送確認包(ACK),SYN 標誌位為0,ACK 標誌位為1,並且把伺服器發來 ACK 的序號欄位+1,放在確定欄位中傳送給對方,並且在資料段放寫seq的+1傳送完畢後,客戶端進入
ESTABLISHED
ESTABLISHED
狀態,TCP 握手結束。
三次握手模擬現實場景:
客戶端:“你好,在家不,有你的快遞?”
服務端:“在的,送上來吧”
客戶端:“好,這就給你送上來”
3 傳送HTTP請求
與伺服器建立了連線後,就可以向伺服器發起請求了。
傳送HTTP請求的過程就是構建HTTP請求報文並通過TCP協議中傳送到伺服器指定埠(HTTP協議80/8080, HTTPS協議443)。HTTP請求報文是由三部分組成: 請求行, 請求報頭和請求正文。
4 伺服器處理請求
伺服器端收到請求後的由web伺服器(準確說應該是http伺服器)處理請求,諸如Apache、Ngnix、IIS等。web伺服器解析使用者請求,知道了需要排程哪些資原始檔,再通過相應的這些資原始檔處理使用者請求和引數,並呼叫資料庫資訊,最後將結果通過web伺服器返回給瀏覽器客戶端。
5 返回響應結果
HTTP響應報文也是由三部分組成: 狀態碼, 響應報頭和響應報文。
狀態碼是由3位陣列成,第一個數字定義了響應的類別,且有五種可能取值:
- 1xx:指示資訊–表示請求已接收,繼續處理。
- 2xx:成功–表示請求已被成功接收、理解、接受。
- 3xx:重定向–要完成請求必須進行更進一步的操作。
- 4xx:客戶端錯誤–請求有語法錯誤或請求無法實現。
- 5xx:伺服器端錯誤–伺服器未能實現合法的請求。 平時遇到比較常見的狀態碼有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分別表示什麼請自行查詢)。
6 關閉TCP連線
為了避免伺服器與客戶端雙方的資源佔用和損耗,當雙方沒有請求或響應傳遞時,任意一方都可以發起關閉請求。與建立TCP連線的3次握手類似,關閉TCP連線,需要4次揮手。
模擬現實場景
客戶端:“兄弟,我這邊沒資料要傳了,咱關閉連線吧。”
服務端:“收到,我看看我這邊有木有資料了。”
服務端:“兄弟,我這邊也沒資料要傳你了,咱可以關閉連線了。”
客戶端:“好嘞。”
7 瀏覽器解析渲染頁面
瀏覽器在收到HTML,CSS,JS檔案後,就需要進行渲染。
瀏覽器是一個邊解析邊渲染的過程。首先瀏覽器解析HTML檔案構建DOM樹,然後解析CSS檔案構建渲染樹,等到渲染樹構建完成後,瀏覽器開始佈局渲染樹並將其繪製到螢幕上。這個過程比較複雜,涉及到兩個概念: reflow(迴流)和repain(重繪)。DOM節點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等,這個過程稱為relow;當盒模型的位置,大小以及其他屬性,如顏色,字型,等確定下來之後,瀏覽器便開始繪製內容,這個過程稱為repain。頁面在首次載入時必然會經歷reflow和repain。reflow和repain過程是非常消耗效能的,尤其是在移動裝置上,它會破壞使用者體驗,有時會造成頁面卡頓。所以我們應該儘可能少的減少reflow和repain。
JS的解析是由瀏覽器中的JS解析引擎完成的。
瀏覽器在解析過程中,如果遇到請求外部資源時,如影象,iconfont,JS等。瀏覽器將重複1-6過程下載該資源。請求過程是非同步的,並不會影響HTML文件進行載入,但是當文件載入過程中遇到JS檔案,HTML文件會掛起渲染過程,不僅要等到文件中JS檔案載入完畢還要等待解析執行完畢,才會繼續HTML的渲染過程。原因是因為JS有可能修改DOM結構,這就意味著JS執行完成前,後續所有資源的下載是沒有必要的,這就是JS阻塞後續資源下載的根本原因。CSS檔案的載入不影響JS檔案的載入,但是卻影響JS檔案的執行。JS程式碼執行前瀏覽器必須保證CSS檔案已經下載並載入完畢。