從URL輸入到頁面展示發生了什麼

總的來說就是下面幾個過程:

DNS解析:將域名解析成IP地址
TCP連接:TCP的三次握手
發送HTTP請求
服務器處理請求並返回HTTP報文
瀏覽器解析渲染頁面
斷開連接:TCP四次揮手
URL到底是啥

URL(Uniform Resource Locator)統一資源定位符,用於定位互聯網上資源,俗稱網絡.遵循以下語法規則:

scheme://host.domain:port/path/filename

scheme:定義因特網服務的類型,常見的類型有:HTTP HTTPS和GTP。
host:定義域主機(http默認是www)
domain:定義因特網域名,比如xxx.com.cn
port:定義主機上的端口號(http:默認是80)
path:定義服務器上的路徑
filename:定義文檔/資源的名稱

1 DNS解析

在瀏覽器輸入網址後,首先要經過域名解析,因爲瀏覽器並不能直接通過域名找到對應的服務器,而是要通過IP地址,之所以我們用的是域名而不是IP,是因爲IP是一段數字,特別不容易記住,而域名其實就是IP的僞裝者。

什麼是域名解析

DNS協議提供通過域名查找IP地址,或者是反向通過IP查找域名的服務。DNS是一個網絡服務器,我們的域名解析簡單來說就是DNS上記錄一條信息記錄。

瀏覽器如何通過域名去查找URL對應的IP的

最厲害的飛機票
上面有飛機,這裏就不詳細解析。

小結

瀏覽器通過DNS服務器發送域名,DNS服務器查詢與域名對應的IP地址,然後返回給瀏覽器,瀏覽器再將IP地址打在協議上,同時請求參數也會在協議搭載,然後一併發送給對方的服務器。接下來介紹向服務器發送HTTP請求階段,HTTP請求分爲三個部分:TCP三次握手,http請求信息,關閉TCP鏈接

2 TCP三次握手

在這裏插入圖片描述

1 三次握手的過程如下:
  • 客戶端發送一個帶有SYN=1和Seq=X的數據報到服務器斷端口(第一次握手是由瀏覽器發起,告訴服務器我要發送請求了)
  • 服務器返回了一個帶SYN=1 ACK=X+1,Seq=Y的響應報以示傳達確認信息(第二次握手,由服務器發送,告訴瀏覽器我準備接受了,你趕緊發送)
  • 客戶端再傳一個帶ACK=Y+1,Seq=Z的數據包,代表"握手結束"(第三次握手,有瀏覽器發送,告訴服務器,我馬上就發了,準備接受吧)
爲啥需要三次握手

主要是爲了防止已失效的連接請求突然又傳送到服務器上。
所謂"已失效的鏈接請求報文段"是這樣產生的,考慮一種正常情況:客戶端發出連接請求,但因連接請求報文丟失而未收到確認,於是客戶端再重傳一次鏈接請求,後來收到了確認,建立了連接。數據傳輸後,就釋放了連接。客戶端共發送了兩個連接請求報文,其中一個丟失,另一個到達了服務器,這樣是沒有失效的連接請求。

但是如果出現一種異常情況,即客戶端發出的第一個連接請求報文文段沒有丟失,而是在某個網絡節點長時間滯留(網差),以致延誤到連接釋放以後的某個時間纔到達服務器,本來這是一個早就已失效的報文段,但服務器收到失效的連接請求報文後,就誤以爲客戶端又發出一次新的連接請求,於是就向客戶端發出確認報文段,同意建立連接,假定不採用報文握手,那麼只要服務器發出確認就建立連接,新的連接就建立了。

由於現在客戶端並沒有發出建立連接的請求,因此不會理會服務器的確認,也不會向服務器發送數據,但是服務器確認爲新的運輸連接已經建立,並一直等待客戶端發來數據,服務器的很多資源就會被浪費。

3 發送HTTP請求

請求報文有請求行,請求頭,請求體組成

請求行大概長這樣

GET/images/logo.gif HTTP/1.1
請求行包含請求方法,URL,協議

請求方法:GET,POST,PUT,DELETE,HEAD,OPTIONS,TRACE,PATCH

請求頭

請求頭包含請求的附加信息,有關鍵字/值對組成,關鍵字和值用英文冒號":"分隔.
請求頭部通知服務器關於客戶端請求的信息,它包含許多有關客戶端環境和請求正文的有用信息。使用keepalive,保持持久連接,一個連接可以發送多個請求.等

請求體

可以承載請求參數的數據,包含回車符,換行符和請求數據

4 服務器處理請求返回HTTP響應報文

主要講HTTP的響應報文

包含協議版本,狀態碼,狀態碼描述

響應行:協議版本,狀態碼,狀態碼描述
響應頭部:響應報文的附加信息,有名/值對組成
響應主題包含回車符,換行符,響應返回數據
4 瀏覽器解析渲染頁面
瀏覽器渲染頁面一共有五個步驟
  • 根據HTML解析出DOM樹
  • 根據CSS解析生成CSS規則樹
  • 結合DOM樹和CSS規則樹,生成渲染樹
  • 根據渲染樹計算每一個節點的信息
  • 根據計算好的信息繪製頁面
1.根據 HTML 解析 DOM 樹
  • 根據 HTML 的內容,將標籤按照結構解析成爲 DOM 樹,DOM 樹解析的過程是一個深度優先遍歷。即先構建當前節點的所有子節點,再構建下一個兄弟節點。
  • 在讀取 HTML 文檔,構建 DOM 樹的過程中,若遇到 script 標籤,則 DOM 樹的構建會暫停,直至腳本執行完畢。
2.根據 CSS 解析生成 CSS 規則樹
  • 解析 CSS 規則樹時 js 執行將暫停,直至 CSS 規則樹就緒。
  • 瀏覽器在 CSS 規則樹生成之前不會進行渲染。
3 結合 DOM 樹和 CSS 規則樹,生成渲染樹
  • DOM 樹和 CSS 規則樹全部準備好了以後,瀏覽器纔會開始構建渲染樹。
  • 精簡 CSS 並可以加快 CSS 規則樹的構建,從而加快頁面相應速度。
4 根據渲染樹計算每一個節點的信息(佈局)
  • 佈局:通過渲染樹中渲染對象的信息,計算出每一個渲染對象的位置和尺寸
  • 迴流:在佈局完成後,發現了某個部分發生了變化影響了佈局,那就需要倒回去重新渲染。
5 根據計算好的信息繪製頁面
  • 繪製階段,系統會遍歷呈現樹,並調用呈現器的“paint”方法,將呈現器的內容顯示在屏幕上
  • 重繪:某個元素的背景顏色,文字顏色等,不影響元素周圍或內部佈局的屬性,將只會引起瀏覽器的重繪。
  • 迴流:某個元素的尺寸發生了變化,則需重新計算渲染樹,重新渲染。
5 斷開鏈接 :TCP四次揮手

在這裏插入圖片描述

  • 客戶端向服務器發送報文Fin=1,seq=u表示已經沒有數據傳輸,並進入FIN-WAIT-1(終止等待1)狀態。 (第一次揮手:客戶端發起,發送給瀏覽器的)
  • 服務器發送報文ACK=1 seq=v ack=u+1 表示同意關閉請求,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。客戶端收到服務器的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最後的數據)
    (第二次揮手:有服務器發起,告訴瀏覽器,我請求報文接受完了,我準備關閉,你也準備吧)
  • 服務器向客戶端發送報文 Fin,ACK等請求關閉連接,進入LAST_ACK狀態(最後確認狀態)
    (第三次揮手:由服務器發起來的,告訴客戶端,我的響應報文發送完了,你準備關閉吧)
  • 客戶端向服務器發送報文段,然後進入TIME_WAIT狀態,服務器收到請求後就關閉連接,客戶端等待一段時間未收到回覆,就正常關閉(第四次揮手:由客戶端發起,告訴服務器,我響應報文接受完了,我準備關閉,你也關閉吧)
爲什麼客戶端在TIME_WAIT狀態必須當代2MSL的時間

1 爲了保證客戶端發送的最後一個ACK報文段能夠到達服務器,這個ACK報文段有可能丟失,因爲使處於LAST-ACK狀態的服務器收不到對方發送的FIN+ACK報文段,服務器會超時重傳FIN+ACK這個報文段,而客戶端就能在2MSL時間內收到這個報文,然後重傳,重新啓動2MSL計時器,最後,客戶端和服務器都正常進入到CLOSED狀態。
如果客戶端沒有等待一段時間,就無法收到服務器發送的重傳報文,因而不會再次發送去確認報文,那麼服務器就無法按照正常步驟進入CLOSED狀

2 防止已失效連接請求報文段,出現在本連接中,客戶端發送完最後一個ACK報文後,再經時間2MSL,就可以是本地連接持續的時間內所產生的所有報文都從網絡中消失,這樣就不會在下一個新連接中出現失效的連接請求報文

爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?

因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

爲什麼不能用兩次握手進行連接?

3次握手完成兩個重要的功能,既要雙方做好發送數據的準備工作(雙方都知道彼此已準備好),也要允許雙方就初始序列號進行協商,這個序列號在握手過程中被髮送和確認。

現在把三次握手改成僅需要兩次握手,死鎖是可能發生的。作爲例子,考慮計算機S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,併發 送了確認應答分組。按照兩次握手的協定,S認爲連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S 是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認爲連接還未建立成功,將忽略S發來的任何數據分 組,只等待連接確認應答分組。而S在發出的分組超時後,重複發送同樣的分組。這樣就形成了死鎖。

如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75分鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章