面試官問:瀏覽器輸入 URL 回車之後發生了什麼?

點擊上方 "程序員小樂"關注, 星標或置頂一起成長

每天凌晨00點00分, 第一時間與你相約


每日英文

If someone hurts you, please continue good good, to enjoy life, hurt the same. One day, that person will be sorry to miss you.

如果有人傷害了你,請一如既往的善良美好,好好享受生活享受愛情,就像沒受過傷一樣。終有一天那個人會後悔錯過你。


每日掏心話

面對嘲笑,總要努力一下,就算破繭變不成蝴蝶,也要變成么蛾子晃花那些人的眼。


來自:https://4ark.me/post/b6c7c0a2.html


面試官問:瀏覽器輸入 URL 回車之後發生了什麼?

程序員小樂(ID:study_tech)第 808 次推文 圖片來自百度


往日回顧:最全最強解析:支付寶系統架構內部剖析(架構圖)


正文


前言這個問題已經是老生常談了,更是經常被作為面試的壓軸題出現,網上也有很多文章,但最近閒的無聊,然後就自己做了一篇筆記,感覺比之前理解更透徹了。注意:本文的步驟是建立在,請求的是一個簡單的 HTTP 請求,沒有 HTTPS、HTTP2、最簡單的 DNS、沒有代理、並且服務器沒有任何問題的基礎上,儘管這是不切實際的。大致流程

  • URL 解析

  • DNS 查詢

  • TCP 連接

  • 處理請求

  • 接受響應

  • 渲染頁面


一、URL 解析

地址解析:首先判斷你輸入的是一個合法的 URL 還是一個待搜索的關鍵詞,並且根據你輸入的內容進行自動完成、字符編碼等操作。HSTS由於安全隱患,會使用 HSTS 強制客戶端使用 HTTPS 訪問頁面其他操作瀏覽器還會進行一些額外的操作,比如安全檢查、訪問限制(之前國產瀏覽器限制 996.icu)。檢查緩存

面試官問:瀏覽器輸入 URL 回車之後發生了什麼?
二、DNS 查詢基本步驟
面試官問:瀏覽器輸入 URL 回車之後發生了什麼?
1. 瀏覽器緩存瀏覽器會先檢查是否在緩存中,沒有則調用系統庫函數進行查詢。2. 操作系統緩存操作系統也有自己的 DNS緩存,但在這之前,會向檢查域名是否存在本地的 Hosts 文件裡,沒有則向 DNS 服務器發送查詢請求。3. 路由器緩存路由器也有自己的緩存。4. ISP DNS 緩存ISP DNS 就是在客戶端電腦上設置的首選 DNS 服務器,它們在大多數情況下都會有緩存。根域名服務器查詢在前面所有步驟沒有緩存的情況下,本地 DNS 服務器會將請求轉發到互聯網上的根域,下面這個圖很好的詮釋了整個流程:
面試官問:瀏覽器輸入 URL 回車之後發生了什麼?
根域名服務器(維基百科)需要注意的點
  • 遞歸方式:一路查下去中間不返回,得到最終結果才返回信息(瀏覽器到本地DNS服務器的過程)

  • 迭代方式,就是本地DNS服務器到根域名服務器查詢的方式。

  • 什麼是 DNS 劫持

  • 前端 dns-prefetch 優化


  • 三、TCP 連接


TCP/IP 分為四層,在發送數據時,每層都要對數據進行封裝:

面試官問:瀏覽器輸入 URL 回車之後發生了什麼?

1. 應用層:發送 HTTP 請求

在前面的步驟我們已經得到服務器的 IP 地址,瀏覽器會開始構造一個 HTTP 報文,其中包括:


  • 請求報頭(Request Header):請求方法、目標地址、遵循的協議等等

  • 請求主體(其他參數)


其中需要注意的點:


  • 瀏覽器只能發送 GET、POST 方法,而打開網頁使用的是 GET 方法


2. 傳輸層:TCP 傳輸報文

傳輸層會發起一條到達服務器的 TCP 連接,為了方便傳輸,會對數據進行分割(以報文段為單位),並標記編號,方便服務器接受時能夠準確地還原報文信息。

在建立連接前,會先進行 TCP 三次握手。

關於 TCP/IP 三次握手,網上已經有很多段子和圖片生動地描述了。

相關知識點:


  • SYN 泛洪攻擊


3. 網絡層:IP協議查詢Mac地址

將數據段打包,並加入源及目標的IP地址,並且負責尋找傳輸路線。

判斷目標地址是否與當前地址處於同一網絡中,是的話直接根據 Mac 地址發送,否則使用路由表查找下一跳地址,以及使用 ARP 協議查詢它的 Mac 地址。

注意:在 OSI 參考模型中 ARP 協議位於鏈路層,但在 TCP/IP 中,它位於網絡層。

4. 鏈路層:以太網協議

以太網協議

根據以太網協議將數據分為以“幀”為單位的數據包,每一幀分為兩個部分:


  • 標頭:數據包的發送者、接受者、數據類型

  • 數據:數據包具體內容


Mac 地址

以太網規定了連入網絡的所有設備都必須具備“網卡”接口,數據包都是從一塊網卡傳遞到另一塊網卡,網卡的地址就是 Mac 地址。每一個 Mac 地址都是獨一無二的,具備了一對一的能力。

廣播

發送數據的方法很原始,直接把數據通過 ARP 協議,向本網絡的所有機器發送,接收方根據標頭信息與自身 Mac 地址比較,一致就接受,否則丟棄。

注意:接收方回應是單播。

相關知識點:


  • ARP 攻擊


服務器接受請求

接受過程就是把以上步驟逆轉過來,參見上圖。

四、服務器處理請求

大致流程

面試官問:瀏覽器輸入 URL 回車之後發生了什麼?
HTTPD最常見的 HTTPD 有 Linux 上常用的 Apache 和 Nginx,以及 Windows 上的 IIS。它會監聽得到的請求,然後開啟一個子進程去處理這個請求。處理請求接受 TCP 報文後,會對連接進行處理,對HTTP協議進行解析(請求方法、域名、路徑等),並且進行一些驗證:
  • 驗證是否配置虛擬主機

  • 驗證虛擬主機是否接受此方法

  • 驗證該用戶可以使用該方法(根據 IP 地址、身份信息等)

  • 重定向假如服務器配置了 HTTP 重定向,就會返回一個 301永久重定向響應,瀏覽器就會根據響應,重新發送 HTTP 請求(重新執行上面的過程)。URL 重寫然後會查看 URL 重寫規則,如果請求的文件是真實存在的,比如圖片、html、css、js文件等,則會直接把這個文件返回。否則服務器會按照規則把請求重寫到 一個 REST 風格的 URL 上。然後根據動態語言的腳本,來決定調用什麼類型的動態文件解釋器來處理這個請求。以 PHP 語言的 MVC 框架舉例,它首先會初始化一些環境的參數,根據 URL 由上到下地去匹配路由,然後讓路由所定義的方法去處理請求。五、瀏覽器接受響應瀏覽器接收到來自服務器的響應資源後,會對資源進行分析。首先查看 Response header,根據不同狀態碼做不同的事(比如上面提到的重定向)。如果響應資源進行了壓縮(比如 gzip),還需要進行解壓。然後,對響應資源做緩存。接下來,根據響應資源裡的 MIME[3] 類型去解析響應內容(比如 HTML、Image各有不同的解析方式)。六、渲染頁面


瀏覽器內核

面試官問:瀏覽器輸入 URL 回車之後發生了什麼?

不同的瀏覽器內核,渲染過程也不完全相同,但大致流程都差不多。

基本流程

面試官問:瀏覽器輸入 URL 回車之後發生了什麼?

6.1. HTML 解析

首先要知道瀏覽器解析是從上往下一行一行地解析的。

解析的過程可以分為四個步驟:

① 解碼(encoding)

傳輸回來的其實都是一些二進制字節數據,瀏覽器需要根據文件指定編碼(例如UTF-8)轉換成字符串,也就是HTML 代碼。

② 預解析(pre-parsing)

預解析做的事情是提前加載資源,減少處理時間,它會識別一些會請求資源的屬性,比如img標籤的src屬性,並將這個請求加到請求隊列中。

③ 符號化(Tokenization)

符號化是詞法分析的過程,將輸入解析成符號,HTML 符號包括,開始標籤、結束標籤、屬性名和屬性值。

它通過一個狀態機去識別符號的狀態,比如遇到狀態都會產生變化。

④ 構建樹(tree construction)

注意:符號化和構建樹是並行操作的,也就是說只要解析到一個開始標籤,就會創建一個 DOM 節點。

在上一步符號化中,解析器獲得這些標記,然後以合適的方法創建DOM對象並把這些符號插入到DOM對象中。













  • <title>Web page parsing/<title>

    Web page parsing

    This is an example Web page.


  • 面試官問:瀏覽器輸入 URL 回車之後發生了什麼?


瀏覽器容錯進制

你從來沒有在瀏覽器看過類似”語法無效”的錯誤,這是因為瀏覽器去糾正錯誤的語法,然後繼續工作。

事件

當整個解析的過程完成以後,瀏覽器會通過DOMContentLoaded事件來通知DOM解析完成。

6.2. CSS 解析

一旦瀏覽器下載了 CSS,CSS 解析器就會處理它遇到的任何 CSS,根據語法規範[4]解析出所有的 CSS 並進行標記化,然後我們得到一個規則表。

CSS 匹配規則

在匹配一個節點對應的 CSS 規則時,是按照從右到左的順序的,例如:div p { font-size :14px }會先尋找所有的p標籤然後判斷它的父元素是否為div。

所以我們寫 CSS 時,儘量用 id 和 class,千萬不要過度層疊。

6.3. 渲染樹

其實這就是一個 DOM 樹和 CSS 規則樹合併的過程。

注意:渲染樹會忽略那些不需要渲染的節點,比如設置了display:none的節點。

計算

通過計算讓任何尺寸值都減少到三個可能之一:auto、百分比、px,比如把rem轉化為px。

級聯

瀏覽器需要一種方法來確定哪些樣式才真正需要應用到對應元素,所以它使用一個叫做specificity的公式,這個公式會通過:


  • 標籤名、class、id

  • 是否內聯樣式

  • !important


然後得出一個權重值,取最高的那個。

渲染阻塞

當遇到一個script標籤時,DOM 構建會被暫停,直至腳本完成執行,然後繼續構建 DOM 樹。

但如果 JS 依賴 CSS 樣式,而它還沒有被下載和構建時,瀏覽器就會延遲腳本執行,直至 CSS Rules 被構建。

所有我們知道:


  • CSS 會阻塞 JS 執行

  • JS 會阻塞後面的 DOM 解析


為了避免這種情況,應該以下原則:


  • CSS 資源排在 JavaScript 資源前面

  • JS 放在 HTML 最底部,也就是


分享到:


相關文章: