深刻瀏覽器之導航流程

前言

「在瀏覽器裏,從輸入 URL 到頁面展現,這中間發生了什麼? 」這是一道經典的面試題,能比較全面地考察應聘者知識的掌握程度,其中涉及到了網絡、操做系統、Web 等一系列的知識。系統而全面的回答這個問題,也就搞懂瀏覽器的導航流程。html

導航流程

從輸入 URL 到頁面展現完整流程示意圖
從輸入 URL 到頁面展現完整流程示意圖

導航的整個流程須要各個進程間的配合,因此咱們要先了解瀏覽器進程、渲染進程和網絡進程的主要職責。面試

  • 瀏覽器進程主要負責用戶交互、子進程管理和文件儲存等功能。
  • 網絡進程是面向渲染進程和瀏覽器進程等提供網絡下載功能。
  • 渲染進程的主要職責是把從網絡下載的 HTML、JavaScript、CSS、圖片等資源解析爲能夠顯示和交互的頁面。由於渲染進程全部的內容都是經過網絡獲取的,會存在一些惡意代碼利用瀏覽器漏洞對系統進行攻擊,因此運行在渲染進程裏面的代碼是不被信任的。這也是爲何 Chrome 會讓渲染進程運行在安全沙箱裏,就是爲了保證系統的安全。

能夠看出,整個流程包含了許多步驟,我把其中幾個核心的節點用藍色背景標記出來了。這個過程能夠大體描述爲以下:瀏覽器

  1. 首先,瀏覽器進程接收到用戶輸入的 URL 請求,瀏覽器進程便將該 URL 轉發給網絡進程。
  2. 而後,在網絡進程中發起真正的 URL 請求。
  3. 接着網絡進程接收到了響應頭數據,便解析響應頭數據,並將數據轉發給瀏覽器進程。
  4. 瀏覽器進程接收到網絡進程的響應頭數據以後,發送「提交導航 (CommitNavigation)」消息到渲染進程;
  5. 渲染進程接收到「提交導航」的消息以後,便開始準備接收 HTML 數據,接收數據的方式是直接和網絡進程創建數據管道;
  6. 最後渲染進程會向瀏覽器進程「確認提交」,這是告訴瀏覽器進程:「已經準備好接受和解析頁面數據了」。
  7. 瀏覽器進程接收到渲染進程「提交文檔」的消息以後,便開始移除以前舊的文檔,而後更新瀏覽器進程中的頁面狀態。

這其中,用戶發出 URL 請求到頁面開始解析的這個過程,就叫作導航。緩存

從輸入 URL 到頁面展現

如今咱們知道了瀏覽器幾個主要進程的職責,還有在導航過程當中須要經歷的幾個主要的階段,下面咱們就來詳細分析下這些階段,同時也就解答了開頭所說的那道經典的面試題。安全

用戶輸入

當用戶在地址欄中輸入一個查詢關鍵字時,地址欄會判斷輸入的關鍵字是搜索內容,仍是請求的 URL服務器

  • 若是是搜索內容,地址欄會使用瀏覽器默認的搜索引擎,來合成新的帶搜索關鍵字的 URL。
  • 若是判斷輸入內容符合 URL 規則,那麼地址欄會根據規則,把這段內容加上協議,合成爲完整的 URL。

當用戶輸入關鍵字並鍵入回車以後,這意味着當前頁面即將要被替換成新的頁面,不過在這個流程繼續以前,瀏覽器還給了當前頁面一次執行 beforeunload 事件的機會,beforeunload 事件容許頁面在退出以前執行一些數據清理操做,還能夠詢問用戶是否要離開當前頁面,好比當前頁面可能有未提交完成的表單等狀況,所以用戶能夠經過 beforeunload 事件來取消導航,讓瀏覽器再也不執行任何後續工做。markdown

此時,頁面顯示的依然是以前打開的頁面內容,並沒當即替換爲新的頁面。由於須要等待提交文檔階段,頁面內容纔會被替換。網絡

URL 請求過程

瀏覽器進程會經過進程間通訊(IPC)把 URL 請求發送至網絡進程,網絡進程接收到 URL 請求後,會在這裏發起真正的 URL 請求流程。併發

具體流程:app

  • 首先,網絡進程會查找本地緩存是否緩存了該資源。若是有緩存資源,那麼直接返回資源給瀏覽器進程;若是在緩存中沒有查找到資源,那麼直接進入網絡請求流程。這請求前的第一步是要進行 DNS 解析,以獲取請求域名的服務器 IP 地址。若是請求協議是 HTTPS,那麼還須要創建 TLS 鏈接。
  • 接下來就是利用 IP 地址和服務器創建 TCP 鏈接。鏈接創建以後,瀏覽器端會構建請求行、請求頭等信息,並把和該域名相關的 Cookie 等數據附加到請求頭中,而後向服務器發送構建的請求信息。
  • 服務器接收到請求信息後,會根據請求信息生成響應數據(包括響應行、響應頭和響應體等信息),併發給網絡進程。等網絡進程接收了響應行和響應頭以後,就開始解析響應頭的內容了。

重定向

在接收到服務器返回的響應頭後,網絡進程開始解析響應頭,若是發現返回的狀態碼是 301 或者 302,那麼說明服務器須要瀏覽器重定向到其餘 URL。這時網絡進程會從響應頭的 Location 字段裏面讀取重定向的地址,而後再發起新的 HTTP 或者 HTTPS 請求,一切又重頭開始了。

在導航過程當中,若是服務器響應行的狀態碼包含了 30一、302 一類的跳轉信息,瀏覽器會跳轉到新的地址繼續導航;若是響應行是 200,那麼表示瀏覽器能夠繼續處理該請求。

響應數據類型處理

在處理了跳轉信息以後,咱們繼續導航流程的分析。URL 請求的數據類型,有時候是一個下載類型,有時候是正常的 HTML 頁面,瀏覽器是經過 Content-Type 字段來區分。Content-Type 是 HTTP 頭中一個很是重要的字段, 它告訴瀏覽器服務器返回的響應體數據是什麼類型,而後瀏覽器會根據 Content-Type 的值來決定如何顯示響應體的內容。

Content-Type 的值是 application/octet-stream,顯示數據是字節流類型的,一般狀況下,瀏覽器會按照下載類型來處理該請求。

須要注意的是,若是服務器配置 Content-Type 不正確,好比將 text/html 類型配置成 application/octet-stream 類型,那麼瀏覽器可能會曲解文件內容,好比會將一個原本是用來展現的頁面,變成了一個下載文件。

因此,不一樣 Content-Type 的後續處理流程也大相徑庭。若是 Content-Type 字段的值被瀏覽器判斷爲下載類型,那麼該請求會被提交給瀏覽器的下載管理器,同時該 URL 請求的導航流程就此結束。但若是是 HTML,那麼瀏覽器則會繼續進行導航流程

準備渲染進程

默認狀況下,Chrome 會爲每一個頁面分配一個渲染進程,也就是說,每打開一個新頁面就會配套建立一個新的渲染進程。可是,也有一些例外,在某些狀況下,瀏覽器會讓多個頁面直接運行在同一個渲染進程中。

具體地講,咱們將「同一站點」定義爲根域名(例如,geekbang.org)加上協議(例如,https:// 或者 http://)

Chrome 的默認策略是,每一個標籤對應一個渲染進程。但若是從一個頁面打開了另外一個新頁面,而新頁面和當前頁面屬於同一站點的話,那麼新頁面會複用父頁面的渲染進程。官方把這個默認策略叫 process-per-site-instance。

總結來講,打開一個新頁面採用的渲染進程策略就是:

  • 一般狀況下,打開新的頁面都會使用單獨的渲染進程;
  • 若是從 A 頁面打開 B 頁面,且 A 和 B 都屬於同一站點的話,那麼 B 頁面複用 A 頁面的渲染進程;

若是是其餘狀況,瀏覽器進程則會爲 B 建立一個新的渲染進程。渲染進程準備好以後,還不能當即進入文檔解析狀態,由於此時的文檔數據還在網絡進程中,並無提交給渲染進程,因此下一步就進入了提交文檔階段。

提交文檔

所謂提交文檔,就是指瀏覽器進程將網絡進程接收到的 HTML 數據提交給渲染進程,具體流程是這樣的:

  • 首先當瀏覽器進程接收到網絡進程的響應頭數據以後,便向渲染進程發起「提交文檔」的消息;
  • 渲染進程接收到「提交文檔」的消息後,會和網絡進程創建傳輸數據的「管道」;
  • 等文檔數據傳輸完成以後,渲染進程會返回「確認提交」的消息給瀏覽器進程;
  • 瀏覽器進程在收到「確認提交」的消息後,會更新瀏覽器界面狀態,包括了安全狀態、地址欄的 URL、前進後退的歷史狀態,並更新 Web 頁面。

這也就解釋了爲何在瀏覽器的地址欄裏面輸入了一個地址後,以前的頁面沒有立馬消失,而是要加載一下子纔會更新頁面。

渲染階段

一旦文檔被提交,渲染進程便開始頁面解析和子資源加載了,關於這個階段的完整過程,能夠繼續閱讀渲染流程

參考文章

瀏覽器工做原理和實踐

本文使用 mdnice 排版

相關文章
相關標籤/搜索