「在瀏覽器裏,從輸入 URL 到頁面展現,這中間發生了什麼? 」這是一道經典的面試題,能比較全面地考察應聘者知識的掌握程度,其中涉及到了網絡、操做系統、Web 等一系列的知識。系統而全面的回答這個問題,也就搞懂瀏覽器的導航流程。html
導航的整個流程須要各個進程間的配合,因此咱們要先了解瀏覽器進程、渲染進程和網絡進程的主要職責。面試
能夠看出,整個流程包含了許多步驟,我把其中幾個核心的節點用藍色背景標記出來了。這個過程能夠大體描述爲以下:瀏覽器
這其中,「用戶發出 URL 請求到頁面開始解析的這個過程,就叫作導航。」緩存
如今咱們知道了瀏覽器幾個主要進程的職責,還有在導航過程當中須要經歷的幾個主要的階段,下面咱們就來詳細分析下這些階段,同時也就解答了開頭所說的那道經典的面試題。安全
當用戶在地址欄中輸入一個查詢關鍵字時,地址欄會判斷輸入的關鍵字是「搜索內容」,仍是「請求的 URL」。服務器
當用戶輸入關鍵字並鍵入回車以後,這意味着當前頁面即將要被替換成新的頁面,不過在這個流程繼續以前,瀏覽器還給了當前頁面一次執行 beforeunload
事件的機會,beforeunload
事件容許頁面在退出以前執行一些數據清理操做,還能夠詢問用戶是否要離開當前頁面,好比當前頁面可能有未提交完成的表單等狀況,所以用戶能夠經過 beforeunload
事件來取消導航,讓瀏覽器再也不執行任何後續工做。markdown
「此時,頁面顯示的依然是以前打開的頁面內容,並沒當即替換爲新的頁面。由於須要等待提交文檔階段,頁面內容纔會被替換。」網絡
瀏覽器進程會經過進程間通訊(IPC)把 URL 請求發送至網絡進程,網絡進程接收到 URL 請求後,會在這裏發起真正的 URL 請求流程。併發
「具體流程:」app
在接收到服務器返回的響應頭後,網絡進程開始解析響應頭,若是發現返回的狀態碼是 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。
總結來講,打開一個新頁面採用的渲染進程策略就是:
若是是其餘狀況,瀏覽器進程則會爲 B 建立一個新的渲染進程。渲染進程準備好以後,還不能當即進入文檔解析狀態,由於此時的文檔數據還在網絡進程中,並無提交給渲染進程,因此下一步就進入了提交文檔階段。
所謂提交文檔,就是指瀏覽器進程將網絡進程接收到的 HTML 數據提交給渲染進程,具體流程是這樣的:
這也就解釋了爲何在瀏覽器的地址欄裏面輸入了一個地址後,以前的頁面沒有立馬消失,而是要加載一下子纔會更新頁面。
一旦文檔被提交,渲染進程便開始頁面解析和子資源加載了,關於這個階段的完整過程,能夠繼續閱讀渲染流程。
本文使用 mdnice 排版