【轉(zhuǎn)】導(dǎo)航流程:從輸入U(xiǎn)RL到頁面展示括勺,這中間發(fā)生了什么?

“在瀏覽器里曲掰,從輸入 URL 到頁面展示疾捍,這中間發(fā)生了什么? ”這是一道經(jīng)典的面試題栏妖,能比較全面地考察應(yīng)聘者知識(shí)的掌握程度乱豆,其中涉及到了網(wǎng)絡(luò)、操作系統(tǒng)吊趾、Web 等一系列的知識(shí)宛裕。所以我在面試應(yīng)聘者時(shí)也必問這道題,但遺憾的是大多數(shù)人只能回答其中部分零散的知識(shí)點(diǎn)论泛,并不能將這些知識(shí)點(diǎn)串聯(lián)成線揩尸,無法系統(tǒng)而又全面地回答這個(gè)問題。

那么今天我們就一起來探索下這個(gè)流程孵奶,下圖是我梳理出的“從輸入 URL 到頁面展示完整流程示意圖”:

image.png

從圖中可以看出疲酌,整個(gè)過程需要各個(gè)進(jìn)程之間的配合,所以在開始正式流程之前,我們還是先來快速回顧下瀏覽器進(jìn)程朗恳、渲染進(jìn)程和網(wǎng)絡(luò)進(jìn)程的主要職責(zé)湿颅。

  • 瀏覽器進(jìn)程主要負(fù)責(zé)用戶交互、子進(jìn)程管理和文件儲(chǔ)存等功能粥诫。
  • 網(wǎng)絡(luò)進(jìn)程是面向渲染進(jìn)程和瀏覽器進(jìn)程等提供網(wǎng)絡(luò)下載功能油航。
  • 渲染進(jìn)程的主要職責(zé)是把從網(wǎng)絡(luò)下載的 HTML、JavaScript怀浆、CSS谊囚、圖片等資源解析為可以顯示和交互的頁面。因?yàn)殇秩具M(jìn)程所有的內(nèi)容都是通過網(wǎng)絡(luò)獲取的执赡,會(huì)存在一些惡意代碼利用瀏覽器漏洞對(duì)系統(tǒng)進(jìn)行攻擊镰踏,所以運(yùn)行在渲染進(jìn)程里面的代碼是不被信任的。這也是為什么 Chrome 會(huì)讓渲染進(jìn)程運(yùn)行在安全沙箱里沙合,就是為了保證系統(tǒng)的安全奠伪。

回顧了瀏覽器的進(jìn)程架構(gòu)后,我們?cè)俳Y(jié)合上圖來看下這個(gè)完整的流程首懈,可以看出绊率,整個(gè)流程包含了許多步驟,我把其中幾個(gè)核心的節(jié)點(diǎn)用藍(lán)色背景標(biāo)記出來了究履。這個(gè)過程可以大致描述為如下滤否。

  • 首先,瀏覽器進(jìn)程接收到用戶輸入的 URL 請(qǐng)求最仑,瀏覽器進(jìn)程便將該 URL 轉(zhuǎn)發(fā)給網(wǎng)絡(luò)進(jìn)程藐俺。

  • 然后,在網(wǎng)絡(luò)進(jìn)程中發(fā)起真正的 URL 請(qǐng)求盯仪。

  • 接著網(wǎng)絡(luò)進(jìn)程接收到了響應(yīng)頭數(shù)據(jù)紊搪,便解析響應(yīng)頭數(shù)據(jù)蜜葱,并將數(shù)據(jù)轉(zhuǎn)發(fā)給瀏覽器進(jìn)程全景。

  • 瀏覽器進(jìn)程接收到網(wǎng)絡(luò)進(jìn)程的響應(yīng)頭數(shù)據(jù)之后,發(fā)送“提交導(dǎo)航 (CommitNavigation)”消息到渲染進(jìn)程牵囤;

  • 渲染進(jìn)程接收到“提交導(dǎo)航”的消息之后爸黄,便開始準(zhǔn)備接收 HTML 數(shù)據(jù),接收數(shù)據(jù)的方式是直接和網(wǎng)絡(luò)進(jìn)程建立數(shù)據(jù)管道揭鳞;

  • 最后渲染進(jìn)程會(huì)向?yàn)g覽器進(jìn)程“確認(rèn)提交”炕贵,這是告訴瀏覽器進(jìn)程:“已經(jīng)準(zhǔn)備好接受和解析頁面數(shù)據(jù)了”。

  • 瀏覽器進(jìn)程接收到渲染進(jìn)程“提交文檔”的消息之后野崇,便開始移除之前舊的文檔称开,然后更新瀏覽器進(jìn)程中的頁面狀態(tài)。

這其中,用戶發(fā)出 URL 請(qǐng)求到頁面開始解析的這個(gè)過程鳖轰,就叫做導(dǎo)航清酥。

1. 用戶輸入

當(dāng)用戶在地址欄中輸入一個(gè)查詢關(guān)鍵字時(shí),地址欄會(huì)判斷輸入的關(guān)鍵字是搜索內(nèi)容蕴侣,還是請(qǐng)求的 URL焰轻。

  • 如果是搜索內(nèi)容,地址欄會(huì)使用瀏覽器默認(rèn)的搜索引擎昆雀,來合成新的帶搜索關(guān)鍵字的 URL辱志。

  • 如果判斷輸入內(nèi)容符合 URL 規(guī)則,比如輸入的是lzugis.cn狞膘,那么地址欄會(huì)根據(jù)規(guī)則揩懒,把這段內(nèi)容加上協(xié)議,合成為完整的 URL挽封,如 https://lzugis.cn旭从。

當(dāng)用戶輸入關(guān)鍵字并鍵入回車之后,這意味著當(dāng)前頁面即將要被替換成新的頁面场仲,不過在這個(gè)流程繼續(xù)之前和悦,瀏覽器還給了當(dāng)前頁面一次執(zhí)行 beforeunload 事件的機(jī)會(huì),beforeunload事件允許頁面在退出之前執(zhí)行一些數(shù)據(jù)清理操作渠缕,還可以詢問用戶是否要離開當(dāng)前頁面鸽素,比如當(dāng)前頁面可能有未提交完成的表單等情況,因此用戶可以通過 beforeunload 事件來取消導(dǎo)航亦鳞,讓瀏覽器不再執(zhí)行任何后續(xù)工作馍忽。

當(dāng)前頁面沒有監(jiān)聽 beforeunload 事件或者同意了繼續(xù)后續(xù)流程,那么瀏覽器便進(jìn)入下圖的狀態(tài):

image.png

開始加載 URL 瀏覽器狀態(tài)從圖中可以看出燕差,當(dāng)瀏覽器剛開始加載一個(gè)地址之后遭笋,標(biāo)簽頁上的圖標(biāo)便進(jìn)入了加載狀態(tài)。但此時(shí)圖中頁面顯示的依然是之前打開的頁面內(nèi)容徒探,并沒立即替換為極客時(shí)間的頁面瓦呼。因?yàn)樾枰却峤晃臋n階段,頁面內(nèi)容才會(huì)被替換测暗。

2. URL 請(qǐng)求過程

接下來央串,便進(jìn)入了頁面資源請(qǐng)求過程。這時(shí)碗啄,瀏覽器進(jìn)程會(huì)通過進(jìn)程間通信(IPC)把 URL 請(qǐng)求發(fā)送至網(wǎng)絡(luò)進(jìn)程质和,網(wǎng)絡(luò)進(jìn)程接收到 URL 請(qǐng)求后,會(huì)在這里發(fā)起真正的 URL 請(qǐng)求流程稚字。那具體流程是怎樣的呢饲宿?

首先厦酬,網(wǎng)絡(luò)進(jìn)程會(huì)查找本地緩存是否緩存了該資源。如果有緩存資源瘫想,那么直接返回資源給瀏覽器進(jìn)程弃锐;如果在緩存中沒有查找到資源,那么直接進(jìn)入網(wǎng)絡(luò)請(qǐng)求流程殿托。這請(qǐng)求前的第一步是要進(jìn)行 DNS 解析霹菊,以獲取請(qǐng)求域名的服務(wù)器 IP 地址。如果請(qǐng)求協(xié)議是 HTTPS支竹,那么還需要建立 TLS 連接旋廷。

接下來就是利用 IP 地址和服務(wù)器建立 TCP 連接。連接建立之后礼搁,瀏覽器端會(huì)構(gòu)建請(qǐng)求行饶碘、請(qǐng)求頭等信息,并把和該域名相關(guān)的 Cookie 等數(shù)據(jù)附加到請(qǐng)求頭中馒吴,然后向服務(wù)器發(fā)送構(gòu)建的請(qǐng)求信息扎运。

服務(wù)器接收到請(qǐng)求信息后,會(huì)根據(jù)請(qǐng)求信息生成響應(yīng)數(shù)據(jù)(包括響應(yīng)行饮戳、響應(yīng)頭和響應(yīng)體等信息)豪治,并發(fā)給網(wǎng)絡(luò)進(jìn)程。等網(wǎng)絡(luò)進(jìn)程接收了響應(yīng)行和響應(yīng)頭之后扯罐,就開始解析響應(yīng)頭的內(nèi)容了负拟。

(1)重定向

在接收到服務(wù)器返回的響應(yīng)頭后,網(wǎng)絡(luò)進(jìn)程開始解析響應(yīng)頭歹河,如果發(fā)現(xiàn)返回的狀態(tài)碼是 301 或者 302掩浙,那么說明服務(wù)器需要瀏覽器重定向到其他 URL。這時(shí)網(wǎng)絡(luò)進(jìn)程會(huì)從響應(yīng)頭的 Location 字段里面讀取重定向的地址秸歧,然后再發(fā)起新的 HTTP 或者 HTTPS 請(qǐng)求厨姚,一切又重頭開始了。

比如键菱,我們?cè)诮K端里輸入以下命令:

curl -I https://lzugis.cn

curl -I + URL的命令是接收服務(wù)器返回的響應(yīng)頭的信息谬墙。執(zhí)行命令后,我們看到服務(wù)器返回的響應(yīng)頭信息如下:


image.png

從圖中可以看出纱耻,服務(wù)器返回的響應(yīng)頭的狀態(tài)碼是 200芭梯,這是告訴瀏覽器一切正常险耀,可以繼續(xù)往下處理該請(qǐng)求了弄喘。

好了,以上是重定向內(nèi)容的介紹∷ξ現(xiàn)在你應(yīng)該理解了蘑志,在導(dǎo)航過程中,如果服務(wù)器響應(yīng)行的狀態(tài)碼包含了 301、302 一類的跳轉(zhuǎn)信息急但,瀏覽器會(huì)跳轉(zhuǎn)到新的地址繼續(xù)導(dǎo)航澎媒;如果響應(yīng)行是 200,那么表示瀏覽器可以繼續(xù)處理該請(qǐng)求波桩。

(2)響應(yīng)數(shù)據(jù)類型處理

在處理了跳轉(zhuǎn)信息之后戒努,我們繼續(xù)導(dǎo)航流程的分析。URL 請(qǐng)求的數(shù)據(jù)類型镐躲,有時(shí)候是一個(gè)下載類型储玫,有時(shí)候是正常的 HTML 頁面,那么瀏覽器是如何區(qū)分它們呢萤皂?

答案是 Content-Type撒穷。Content-Type 是 HTTP 頭中一個(gè)非常重要的字段, 它告訴瀏覽器服務(wù)器返回的響應(yīng)體數(shù)據(jù)是什么類型裆熙,然后瀏覽器會(huì)根據(jù) Content-Type 的值來決定如何顯示響應(yīng)體的內(nèi)容端礼。這里我們還是以極客時(shí)間為例,看看lzugis官網(wǎng)返回的 Content-Type 值是什么入录。在終端輸入以下命令:

curl -I https://lzugis.cn

我們看到服務(wù)器返回如下信息:


image.png

從圖中可以看到蛤奥,響應(yīng)頭中的 Content-type字段的值是 text/html,這就是告訴瀏覽器僚稿,服務(wù)器返回的數(shù)據(jù)是 HTML 格式喻括。

3. 準(zhǔn)備渲染進(jìn)程

默認(rèn)情況下,Chrome 會(huì)為每個(gè)頁面分配一個(gè)渲染進(jìn)程贫奠,也就是說唬血,每打開一個(gè)新頁面就會(huì)配套創(chuàng)建一個(gè)新的渲染進(jìn)程。但是唤崭,也有一些例外拷恨,在某些情況下,瀏覽器會(huì)讓多個(gè)頁面直接運(yùn)行在同一個(gè)渲染進(jìn)程中谢肾。

image.png

從圖中可以看出腕侄,打開的這三個(gè)頁面都是運(yùn)行在同一個(gè)渲染進(jìn)程中,進(jìn)程 ID 是 80384芦疏。那什么情況下多個(gè)頁面會(huì)同時(shí)運(yùn)行在一個(gè)渲染進(jìn)程中呢冕杠?要解決這個(gè)問題,我們就需要先了解下什么是同一站點(diǎn)(same-site)酸茴。具體地講分预,我們將“同一站點(diǎn)”定義為根域名(例如,lzugis.cn)加上協(xié)議(例如薪捍,https:// 或者 http://)笼痹,還包含了該根域名下的所有子域名和不同的端口配喳,比如下面這三個(gè):

https://edu.lzugis.cn
https://www.lzugis.cn
https://www.lzugis.cn:8080

它們都是屬于同一站點(diǎn),因?yàn)樗鼈兊膮f(xié)議都是 HTTPS凳干,而且根域名也都是 lzugis.cn晴裹。

Chrome 的默認(rèn)策略是,每個(gè)標(biāo)簽對(duì)應(yīng)一個(gè)渲染進(jìn)程救赐。但如果從一個(gè)頁面打開了另一個(gè)新頁面涧团,而新頁面和當(dāng)前頁面屬于同一站點(diǎn)的話,那么新頁面會(huì)復(fù)用父頁面的渲染進(jìn)程经磅。官方把這個(gè)默認(rèn)策略叫 process-per-site-instance少欺。

總結(jié)來說,打開一個(gè)新頁面采用的渲染進(jìn)程策略就是:

  • 通常情況下馋贤,打開新的頁面都會(huì)使用單獨(dú)的渲染進(jìn)程赞别;
  • 如果從 A 頁面打開 B 頁面,且 A 和 B 都屬于同一站點(diǎn)的話配乓,那么 B 頁面復(fù)用 A 頁面的渲染進(jìn)程仿滔;如果是其他情況,瀏覽器進(jìn)程則會(huì)為 B 創(chuàng)建一個(gè)新的渲染進(jìn)程犹芹。

渲染進(jìn)程準(zhǔn)備好之后崎页,還不能立即進(jìn)入文檔解析狀態(tài),因?yàn)榇藭r(shí)的文檔數(shù)據(jù)還在網(wǎng)絡(luò)進(jìn)程中腰埂,并沒有提交給渲染進(jìn)程飒焦,所以下一步就進(jìn)入了提交文檔階段。

4. 提交文檔

所謂提交文檔屿笼,就是指瀏覽器進(jìn)程將網(wǎng)絡(luò)進(jìn)程接收到的 HTML 數(shù)據(jù)提交給渲染進(jìn)程牺荠,具體流程是這樣的:

  • 首先當(dāng)瀏覽器進(jìn)程接收到網(wǎng)絡(luò)進(jìn)程的響應(yīng)頭數(shù)據(jù)之后,便向渲染進(jìn)程發(fā)起“提交文檔”的消息驴一;

  • 渲染進(jìn)程接收到“提交文檔”的消息后休雌,會(huì)和網(wǎng)絡(luò)進(jìn)程建立傳輸數(shù)據(jù)的“管道”;

  • 等文檔數(shù)據(jù)傳輸完成之后肝断,渲染進(jìn)程會(huì)返回“確認(rèn)提交”的消息給瀏覽器進(jìn)程杈曲;

  • 瀏覽器進(jìn)程在收到“確認(rèn)提交”的消息后,會(huì)更新瀏覽器界面狀態(tài)胸懈,包括了安全狀態(tài)担扑、地址欄的 URL、前進(jìn)后退的歷史狀態(tài)趣钱,并更新 Web 頁面涌献。

其中,當(dāng)渲染進(jìn)程確認(rèn)提交之后羔挡,更新內(nèi)容如下圖所示:

image.png

這也就解釋了為什么在瀏覽器的地址欄里面輸入了一個(gè)地址后洁奈,之前的頁面沒有立馬消失间唉,而是要加載一會(huì)兒才會(huì)更新頁面绞灼。到這里利术,一個(gè)完整的導(dǎo)航流程就“走”完了,這之后就要進(jìn)入渲染階段了低矮。

5. 渲染階段

一旦文檔被提交印叁,渲染進(jìn)程便開始頁面解析和子資源加載了,一旦頁面生成完成军掂,渲染進(jìn)程會(huì)發(fā)送一個(gè)消息給瀏覽器進(jìn)程轮蜕,瀏覽器接收到消息后,會(huì)停止標(biāo)簽圖標(biāo)上的加載動(dòng)畫蝗锥。

至此跃洛,一個(gè)完整的頁面就生成了。那文章開頭的“從輸入 URL 到頁面展示终议,這中間發(fā)生了什么汇竭?”這個(gè)過程及其“串聯(lián)”的問題也就解決了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末穴张,一起剝皮案震驚了整個(gè)濱河市细燎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌皂甘,老刑警劉巖玻驻,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異偿枕,居然都是意外死亡璧瞬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門渐夸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彪蓬,“玉大人,你說我怎么就攤上這事捺萌〉刀” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵桃纯,是天一觀的道長酷誓。 經(jīng)常有香客問我,道長态坦,這世上最難降的妖魔是什么盐数? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮伞梯,結(jié)果婚禮上玫氢,老公的妹妹穿的比我還像新娘帚屉。我一直安慰自己,他們只是感情好漾峡,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布攻旦。 她就那樣靜靜地躺著,像睡著了一般生逸。 火紅的嫁衣襯著肌膚如雪牢屋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天槽袄,我揣著相機(jī)與錄音烙无,去河邊找鬼。 笑死遍尺,一個(gè)胖子當(dāng)著我的面吹牛截酷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乾戏,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼迂苛,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了歧蕉?” 一聲冷哼從身側(cè)響起灾部,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惯退,沒想到半個(gè)月后赌髓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡催跪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年锁蠕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懊蒸。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荣倾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出骑丸,到底是詐尸還是另有隱情舌仍,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布通危,位于F島的核電站铸豁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏菊碟。R本人自食惡果不足惜节芥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧头镊,春花似錦蚣驼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至厂捞,卻和暖如春输玷,著一層夾襖步出監(jiān)牢的瞬間队丝,已是汗流浹背靡馁。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留机久,地道東北人臭墨。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像膘盖,于是被迫代替她去往敵國和親胧弛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容