【瀏覽器】從URL輸入到頁面展現到底發生了什麼?

前言

最近在進行前端面試方面的一些準備,看了網上許多相關的文章,發現有一個問題始終繞不開: 在瀏覽器中輸入URL到整個頁面顯示在用戶面前時這個過程中到底發生了什麼。仔細思考這個問題,發現確實很深,這個過程涉及到的東西很多。這個問題的回答真的能夠很好的考驗一個web工程師的水平,於是特意抽出時間來總結一下。

先給大家來張總體流程圖:
總體流程

總體來說分爲以下幾個過程:

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

一、什麼是URL?

URL(Uniform Resource Locator),統一資源定位符,用於定位互聯網上資源,俗稱網址。

scheme: // host.domain:port / path / filename ? abc = 123 # 456789

scheme       - 定義因特網服務的類型。常見的協議有 http、https、ftp、file,
               其中最常見的類型是 http,而 https 則是進行加密的網絡傳輸。
host         - 定義域主機(http 的默認主機是 www)
domain       - 定義因特網域名,比如 baidu.com
port         - 定義主機上的端口號(http 的默認端口號是 80)
path         - 定義服務器上的路徑(如果省略,則文檔必須位於網站的根目錄中)。
filename     - 定義文檔/資源的名稱
query        - 即查詢參數
fragment     - 即 # 後的hash值,一般用來定位到某個位置

二、DNS域名解析

在瀏覽器輸入網址後,首先要經過域名解析,因爲瀏覽器並不能直接通過域名找到對應的服務器,而是要通過 IP 地址。

  1. IP 地址

    IP 地址是指互聯網協議地址,是 IP Address 的縮寫。IP 地址是 IP 協議提供的一種統一的地址格式,
    它爲互聯網上的每一個網絡和每一臺主機分配一個邏輯地址,以此來屏蔽物理地址的差異。

  2. 什麼是域名解析

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

  3. 瀏覽器如何通過域名去查詢 URL 對應的 IP 呢?

    DNS域名解析分爲遞歸查詢和迭代查詢兩種方式,現一般爲迭代查詢。
    DNS域名解析過程

  4. 小結

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

擴展:DNS優化

  • DNS緩存:DNS存在着多級緩存,從離瀏覽器的距離排序的話,有以下幾種:
    瀏覽器緩存,系統緩存,路由器緩存,IPS服務器緩存,根域名服務器緩存,頂級域名服務器緩存,主域名服務器緩存。
  • DNS負載均衡(DNS重定向):DNS負載均衡技術的實現原理是在DNS服務器中爲同一個主機名配置多個IP地址,在應答DNS查詢時,DNS服務器對每個查詢將以DNS文件中主機記錄的IP地址按順序返回不同的解析結果,將客戶端的訪問引導到不同的機器上去,使得不同的客戶端訪問不同的服務器,從而達到負載均衡的目的。

三、TCP三次握手

在客戶端發送數據之前會發起 TCP 三次握手用以同步客戶端和服務端的序列號和確認號,並交換 TCP 窗口大小信息。
三次握手時序圖

  1. TCP 三次握手的過程如下:

    • 客戶端發送一個帶 SYN=1,Seq=X 的數據包到服務器端口(第一次握手,由瀏覽器發起,告訴服務器我要發送請求了)
    • 服務器發回一個帶 SYN=1, ACK=X+1,Seq=Y的響應包以示傳達確認信息(第二次握手,由服務器發起,告訴瀏覽器我準備接受了,你趕緊發送吧)
    • 客戶端再回傳一個帶 ACK=Y+1, Seq=Z 的數據包,代表“握手結束”(第三次握手,由瀏覽器發送,告訴服務器,我馬上就發了,準備接受吧)
  2. 爲啥需要三次握手
    謝希仁著《計算機網絡》中講“三次握手”的目的是“爲了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤”。

四、發送 HTTP 請求

TCP 三次握手結束後,開始發送 HTTP 請求報文。 請求報文由請求行(request line)、請求頭(header)、請求體四個部分組成,如下圖所示:
請求報文

  1. 請求行包含請求方法、URL、協議版本

    • 請求方法包含 8 種:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
    • URL 即請求地址,由 <協議>://<主機>:<端口>/<路徑>?<參數> 組成
    • 協議版本即 http 版本號

    POST /chapter17/user.html HTTP/1.1

    以上代碼中“POST”代表請求方法,“/chapter17/user.html”表示URL,“HTTP/1.1”代表協議和協議的版本。現在比較流行的是 Http1.1 版本

  2. 請求頭包含請求的附加信息,由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。

    請求頭部通知服務器有關於客戶端請求的信息。它包含許多有關的客戶端環境和請求正文的有用信息。其中比如:Host,表示主機名,虛擬主機;Connection,HTTP/1.1 增加的,使用 keepalive,即持久連接,一個連接可以發多個請求;User-Agent,請求發出者,兼容性以及定製化需求。

  3. 請求體,可以承載多個請求參數的數據,包含回車符、換行符和請求數據,並不是所有請求都具有請求數據。

    name=tom&password=1234&realName=tomson

    上面代碼,承載着 name、password、realName 三個請求參數。

五、服務器處理請求並返回 HTTP 報文

每臺服務器上都會安裝處理請求的應用——Web server。常見的web server產品有apache、nginx、IIS、Lighttpd等。但大部分都還是按照 MVC 設計模式進行搭建的。
MVC 後臺處理階段

六、瀏覽器解析渲染頁面

爲避免篇幅過長,瀏覽器渲染相關內容請參閱: 【瀏覽器】渲染原理探究

七、斷開連接

當數據傳送完畢,需要斷開 tcp 連接,此時發起 tcp 四次揮手。
TCP 四次揮手

  • 發起方向被動方發送報文,Fin、Ack、Seq,表示已經沒有數據傳輸了。並進入 FIN_WAIT_1 狀態。(第一次揮手:由瀏覽器發起的,發送給服務器,我請求報文發送完了,你準備關閉吧)
  • 被動方發送報文,Ack、Seq,表示同意關閉請求。此時主機發起方進入 FIN_WAIT_2 狀態。(第二次揮手:由服務器發起的,告訴瀏覽器,我請求報文接受完了,我準備關閉了,你也準備吧)
  • 被動方向發起方發送報文段,Fin、Ack、Seq,請求關閉連接。並進入 LAST_ACK 狀態。(第三次揮手:由服務器發起,告訴瀏覽器,我響應報文發送完了,你準備關閉吧)
  • 發起方向被動方發送報文段,Ack、Seq。然後進入等待 TIME_WAIT 狀態。被動方收到發起方的報文段以後關閉連接。發起方等待一定時間未收到回覆,則正常關閉。(第四次揮手:由瀏覽器發起,告訴服務器,我響應報文接受完了,我準備關閉了,你也準備吧)

後記:
小夥伴們,如果有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。如果覺得本文還不錯,記得點個贊哦!
本文首發地址爲: Vae’s Blog

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