從輸入URL到頁面展示,這中間發生了那些過程(1)?
從輸入URL到頁面展示,這中間發生了那些過程?這是一道十分經典的面試題,我們應該首先從巨集觀的角度,也就是瀏覽器的多程序架構來分析這個過程中有哪些程序有參與和配合?其次我們應該從微觀的角度細緻入微的搞清楚每一個步驟發生了什麼事情,只有這樣才可以完整清晰的回答好這個面試題。
瀏覽器多程序間的協作過程
在這整個過程中,瀏覽器的主程序、渲染程序和網路程序參與了工作,它們是互相配合來完成這一從輸入URL到頁面展示的流程的,三個程序的主要分工如下:
- 瀏覽器程序:主要負責管理各個子程序、頁面互動和檔案儲存功能
- 渲染程序:主要負責將網路程序中載入好的HTML、CSS、Javascript和圖片等資源進行解析渲染,對於Chrome來說其渲染引擎blink和JS解析引擎V8都是在這個程序中工作的
- 網路程序:主要負責發起HTTP請求,將伺服器返回的資源進行下載
瞭解了以上三個程序的主要功能之後,就可以從瀏覽器程序的角度來分析以下輸入URL到頁面展示經歷了那些過程:
- 瀏覽器程序接收到使用者輸入的URL地址,瀏覽器程序會將其URL地址轉發給網路程序
- 網路程序發起真正的HTTP請求
- 隨後,網路程序接收到伺服器返回的響應頭資料,開始解析響應頭資料,並將資料轉發給瀏覽器主程序
- 瀏覽器主程序接收到響應頭資料,傳送一個名為"提交導航CommitNavigation"d的訊息給渲染程序
- 渲染程序接收到"CommitNavigation"的訊息之後,便和網路程序建立一個管道,開始準備接收HTML資料
- 準備好之後,渲染程序向主程序傳送一個"確認提交"的資訊,此時便等於告訴瀏覽器可以開始接收和解析資料了
- 瀏覽器程序中接收到渲染程序"提交文件"的訊息之後,便開始移除舊的文件,更新頁面
從輸入URL到頁面展示的詳細流程
1. 使用者輸入
瀏覽器首先會判斷使用者在位址列中輸入的是查詢關鍵字還是合法的URL地址?
如果是查詢關鍵字,那麼瀏覽器會基於當前設定的預設的搜尋引擎來合成帶搜尋關鍵字的URL
如果是合法的URL地址,那麼瀏覽器會將URL地址提交給網路程序
注意:在正式發起請求之前,還需要判定當前頁面是否綁定了onbeforeunload事件
-
beforeunload事件何時觸發
beforeunload事件在當頁面解除安裝(關閉)或重新整理時呼叫,事件觸發的時候彈出一個有確定和取消的對話方塊,確定則離開頁面,取消則繼續待在本頁。 -
繫結beforeunload事件的場景
清理一些多餘的資料,清除定時器
在表單收集的頁面,可以詢問使用者是否確定退出,避免當前頁面有未提交的表單
攔截瀏覽器的導航,讓瀏覽器不在執行後續的跳轉
如果頁面沒有監聽beforeunload事件或者同意繼續之後,瀏覽器標籤頁左上角的favicon便開始展示為loading狀態,此時瀏覽器程序會基於程序間通訊IPC的方式將URL地址轉發給網路程序,用於發起正式的HTTP請求。
2. URL請求流程
查詢快取
首先查詢瀏覽器本地是否快取了需要請求的資源(關於瀏覽器的快取策略後續會專門寫一篇文章來進行說明),如果本次快取中有那麼直接將資源返回給瀏覽器程序;如果沒有查詢到那麼直接進入真正網路請求的流程。
DNS解析獲取IP地址
基於URL地址確認請求的伺服器的IP地址和埠號,IP地址是基於DNS域名解析服務進行查詢,當前DNS也會在瀏覽器本地有快取,如果有快取直接獲取即可。埠號的話一般HTTP協議是80;HTTPS協議是443埠。至於為什麼要獲取IP地址和埠號,這是因為HTTP協議是應用層的協議,傳輸資料是基於底層的tcp協議和ip協議來進行傳輸的,具體的做法是在傳輸的資料包前面加上一個tcp頭資訊和ip頭。
注意如果這裡是https請求的話,還需要在建立TCP連線之間建立TLS連線。
建立TCP連線
基於IP地址和伺服器建立TCP連線,這裡就設計到客戶端和伺服器的三次握手操作,也就是雙方會總共傳送3個數據包來確認建立連線。
瀏覽器傳送請求
瀏覽器端開始構建請求行、請求頭和請求體等資訊,將瀏覽器的一些基礎資訊和cookie等資訊新增到請求頭中,然後向伺服器傳送構建好的請求報文。
伺服器響應資料
服務端接受到請求報文之後,會根據報文資訊生成響應頭、響應行和響應體等資料,等網路程序接受到響應頭和響應行之後,就可以解析響應頭中的內容。等網路程序解析完成響應頭資訊之後,將會將其轉發給瀏覽器程序處理
影響後續流程的兩個資訊
-
響應行中的301/302狀態碼 執行重定向
解析響應頭時還需要注意一個重定向的操作:如果返回的是響應行資訊為301/302,代表需要進行重定向至其他URL地址,此時網路程序會從響應頭中讀取到location欄位的值,並重新發起http/https請求。 -
響應頭中的Content-Type
網路程序會首先基於響應頭中的Content-Type欄位來確定伺服器返回的何種型別的資原始檔,因為不同的資源型別瀏覽器對其處理不一樣:
-
如果這裡接收到的是一個text/html型別的檔案的話,那麼意味這是一個HTML型別的檔案,此時網路程序將響應頭資料轉發給瀏覽器程序,瀏覽器程序就通知渲染程序要準備渲染了。
-
而如果是一個application/octet-stream也就是二進位制位元組流型別的檔案,那麼瀏覽器會將其提交給下載管理器進行下載。
3. 準備渲染程序
一般情況下,瀏覽器主程序會為每一個標籤頁都準備一個渲染程序,但是這裡有一個特殊情況,那就是如果當前頁面和新的頁面屬於同一站點,那麼新的頁面不會再有新的渲染程序,而是複用原來的渲染程序。
什麼是同一站點?
同一站點的意思就是站點與站點之間的協議和根域名相同,那麼根域名下的所有子域名以及所有埠號組成的站點都屬於同一站點。
渲染程序準備好之後,還不能立即進入解析文件的流程,因為此時資源還在網路程序,還沒有提交給渲染程序,那麼下一步就是提交文件階段。
4. 提交文件
當瀏覽器程序接收到網路程序的響應頭資料之後,便向渲染程序傳送一個“提交文件”的資訊
渲染程序接受到該資訊之後,便基於IPC建立和網路程序的資料傳輸管道
隨後便是等待文件傳輸完成之後,渲染程序會返回一個"確認提交"的資訊給瀏覽器主程序
瀏覽器主程序在收到該訊息之後,此時會更新新頁面的安全狀態、前進後退狀態。
5. 渲染頁面
一旦文件確認提交之後,渲染程序就開始解析資源和渲染頁面了,注意瀏覽器的渲染頁面不是等待所有資源都載入完成之後才開始渲染,而是一邊解析一遍渲染的,這也是為什麼有的頁面會先給使用者呈現文字,然後圖片等資源才會隨後載入。