用URL請求頁面流程

重要申明:感謝原文作者——Mervyn Zhang,想看原文請戳這裏!我借鑑了原文,修改了一些原文行文不通暢之處,增加了一些自己希望看到的東西,望請勿怪。掛在自己的博客下面一方面是爲了收藏好文,方便自己溫顧而知新;另一方面也希望更多人看到這文章。

一、引言

前端不僅要讓用戶對網頁有完美的體驗,讓用戶儘快體驗到完美的網頁也是很重要的,這就要前端攻城獅掌握一些網絡原理相關的知識了。這裏就來聊一聊從用戶輸入 url 到頁面加載完成的過程中都發生了什麼事情?

二、正文

用戶輸入 url 之後大致發生了以下幾件事:

  1. 瀏覽器查找域名的 IP 地址。這一步包括 DNS 具體的查找過程,包括:瀏覽器緩存 -> 系統緩存 -> 路由器緩存……
  2. 瀏覽器向 web 服務器發送一個 http 請求:三次握手、傳送數據、四次揮手;
  3. 服務器的永久重定向響應:返回真正訪問的地址;
  4. 瀏覽器跟蹤重定向地址:另發一個 http 請求;
  5. 服務器處理請求;
  6. 服務器返回一個 http 響應;
  7. 瀏覽器顯示 html 頁面:解析 html 以構建 DOM 樹 –> 構建渲染樹 –> 佈局渲染樹 –> 繪製渲染樹;
  8. 瀏覽器發送請求,獲取嵌入在 html 中的資源(如圖片、音頻、視頻、CSSJS 等等);
  9. 瀏覽器發送異步請求。

順便附上 http 狀態碼 (其他狀態碼的詳情,請戳這裏)

http 狀態碼 詳細狀態碼 狀態原因
1xx 消息
2xx 成功
3xx 重定向
4xx 客戶端錯誤
5xx 服務器錯誤
5xx 500 接口報錯了
5xx 502 後端服務沒啓
5xx 503 啓動掛了

下面我們就詳細地瞭解一下這些過程:

1. DNS 查找 IP 地址

DNS域名系統 (Domain Name System) 的縮寫,是因特網的一項核心服務。它作爲可以將域名和 IP 地址相互映射的一個分佈式數據庫,能夠使人更方便的訪問互聯網,而不用去記住能夠被機器直接讀取的 IP 數字串。

  1. DNS 查找過程:

    1. 瀏覽器緩存 —— 瀏覽器會緩存 DNS 記錄一段時間,但是操作系統並沒有告訴瀏覽器儲存 DNS 記錄的時間。於是,不同瀏覽器會儲存各自的一個固定時間( 2 分鐘到 30 分鐘不等)
    2. 系統緩存 – 如果在瀏覽器緩存裏沒有找到需要的記錄,瀏覽器會做一個系統調用( Windows 裏是 gethostbyname ),這樣便可獲得並查詢系統緩存中的記錄。
    3. 路由器緩存 – 接着,前面的查詢請求發向路由器。路由器一般會有自己的 DNS 緩存。
    4. ISP DNS緩存 – 接下來要 check 的就是 ISP 緩存 DNS 的服務器。ISP (Internet Service Provider) 就是互聯網服務提供商,在這一般都能找到相應的緩存記錄。
    5. 遞歸搜索 – 你的 ISPDNS 服務器從跟域名服務器開始進行遞歸搜索,從 .com 頂級域名服務器到 example 的域名服務器。一般 DNS 服務器的緩存中會有 .com 域名服務器中的域名,所以到頂級服務器的匹配過程不是那麼必要了。
  2. DNS 進行域名解析的過程

    1. 客戶端發出 DNS 請求翻譯 IP 地址或主機名;
    2. DNS 服務器在收到客戶端的請求後,檢查 DNS 服務器的緩存,若查到請求的地址或名字,即向客戶端發出應答信息;
    3. 若沒有查到,則在數據庫中查找,若查到請求的地址或名字,即向客戶端發出應答信息;
    4. 若沒有查到,則將請求發給根域 DNS 服務器,並依序從根域查找頂級域,由頂級查找二級域,二級域查找三級,直至找到要解析的地址或名字。然後,向客戶端所在網絡的 DNS 服務器發出應答信息,DNS 服務器收到應答後,先在緩存中存儲,然後,將解析結果發給客戶端。
    5. 若沒有找到,則返回錯誤信息。

2. http請求

  1. 三次握手建立 TCP 連接

    http 工作開始之前,瀏覽器首先要通過網絡與服務器建立連接,該連接是通過 TCP 來完成的。該協議與 IP 協議共同構建 Internet ,即著名的 TCP/IP 協議族,因此 Internet 又被稱作是 TCP/IP 網絡。 http 是比 TCP 更高層次的應用層協議。根據規則,只有低層協議建立之後才能進行更高次層協議的連接。因此,首先要建立 TCP 連接,一般 TCP 連接的端口號是 80 。在 TCP/IP 協議中,TCP 協議提供可靠的連接服務,採用三次握手建立一個連接:

    1. 第一次握手:建立連接時,客戶端發送 SYN(syn=j)到服務器,並進入 SYN_SENT 狀態,等待服務器確認;SYN:同步序列編號(Synchronize Sequence Numbers)
    2. 第二次握手:服務器收到 SYN 包,必須確認客戶的 SYN(ack=j+1),同時自己也發送一個 SYN(syn=k),即 SYN+ACK 包,此時服務器進入 SYN_RECV 狀態;
    3. 第三次握手:客戶端收到服務器的 SYN+ACK 包,向服務器發送確認包 ACK(ack=k+1),此包發送完畢,客戶端和服務器進入 ESTABLISHED(TCP連接成功)狀態,完成三次握手。

    完成三次握手,客戶端與服務器開始傳送數據。

    一旦建立了 TCP 連接,瀏覽器就會向服務器發送 http 請求命令。瀏覽器發送其請求命令之後,還要以頭信息的形式向服務器發送一些別的信息。此後,瀏覽器發送了一空白行來通知服務器,它已經結束了該頭信息的發送。

  2. 四次揮手終止連接

    由於 TCP 連接是全雙工的,因此每個方向都必須單獨進行關閉。原則是當一方完成它的數據發送任務後,就能發送一個 FIN 來終止這個方向的連接。收到一個 FIN 只意味着這一方向上沒有數據流動。一個 TCP 連接在收到一個 FIN 後仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

    1. 第一次揮手:TCP 客戶端發送一個 FIN,用來關閉客戶端到服務器的數據傳送。
    2. 第二次揮手:服務器收到這個 FIN,它發回一個 ACK,確認序號爲收到的序號加 1 。和 SYN 一樣,一個 FIN 將佔用一個序號。
    3. 第三次揮手:服務器關閉客戶端的連接,發送一個 FIN 給客戶端。
    4. 第四次揮手:客戶端發回 ACK 報文確認,並將確認序號設置爲收到序號加 1

3. 服務器的永久重定向響應

服務器給瀏覽器響應一個 301 永久重定向響應,這樣瀏覽器就會訪問 http://www.facebook.com/ 而非 http://facebook.com/

爲什麼服務器一定要重定向而不是直接發會用戶想看的網頁內容呢?這個問題有好多有意思的答案。

其中一個原因跟搜索引擎排名有關。你看,如果一個頁面有兩個地址,就像 http://www.igoro.com/http://igoro.com/ ,搜索引擎會認爲它們是兩個網站,結果造成每一個的搜索鏈接都減少從而降低排名。而搜索引擎知道 301 永久重定向是什麼意思,這樣就會把訪問帶 www 的和不帶 www 的地址歸到同一個網站排名下。

還有一個原因是用不同的地址會造成緩存友好性變差。當一個頁面有好幾個名字時,它可能會在緩存裏出現好幾次。

4. 瀏覽器跟蹤重定向地址

現在,瀏覽器知道了 http://www.facebook.com/ 纔是要訪問的正確地址,所以它會發送另一個獲取請求。

5. 服務器“處理”請求

服務器接收到獲取請求,然後處理並返回一個響應。

6. 頁面渲染

現代瀏覽器渲染頁面的過程是這樣的:解析 html 以構建 DOM 樹 –> 構建渲染樹 –> 佈局渲染樹 –> 繪製渲染樹

DOM 樹是由 html 文件中的標籤排列組成。

渲染樹是在 DOM 樹中加入 csshtml 中的 style 樣式而形成。渲染樹只包含需要顯示在頁面中的 DOM 元素,像 <head> 元素或 display 屬性值爲 none 的元素都不在渲染樹中。在瀏覽器還沒接收到完整的 html 文件時,它就開始渲染頁面了。

在遇到外部鏈入的腳本標籤、樣式標籤、圖片時,會再次發送 http 請求重複上述的步驟。在收到 css 文件後,會對已經渲染的頁面重新渲染,加入它們應有的樣式。圖片文件加載完,立刻顯示在相應位置。在這一過程中可能會觸發頁面的重繪或重排

三、結語

做前端不僅要掌握前端的知識,對一些前端相關的例如計算機網絡、數據結構、計算機原理都要有一定的瞭解,因爲網絡世界連接在一起的,前端與這些知識都是有接觸的,說不準什麼時候就會用上。而且,學好這些知識,對前端優化也有很大的幫助。

發佈了45 篇原創文章 · 獲贊 57 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章