描述一下從輸入U(xiǎn)RL到瀏覽器頁面渲染的過程
以下內(nèi)容會(huì)根據(jù)本人水平的變化不定期更新答案涯肩,目標(biāo)是寫出一個(gè)完整的全方位的答案
目錄
- HSTS 和 dns解析
- Rap協(xié)議解析MAC地址
- 瀏覽器的強(qiáng)緩存或者協(xié)商緩存的觸發(fā)
- 瀏覽器進(jìn)程對(duì)請(qǐng)求返回的數(shù)據(jù)的解析
- 頁面的渲染
從輸入url到HSTS
首先寂屏,我們?cè)趗rl地址欄開始輸入時(shí)蝴乔,瀏覽器根據(jù)你的輸入動(dòng)態(tài)匹配是否對(duì)地址有緩存莫其,如下圖:
然后,假設(shè)當(dāng)前我們就是要輸入baidu的地址氏身,直接回車即可互捌。這里需要注意的是,我們直接baidu.com的形式訪問辐棒,發(fā)起的是http請(qǐng)求病曾,而如果啟用了HSTS,那么瀏覽器會(huì)自動(dòng)幫你重定向漾根,然后把請(qǐng)求協(xié)議改為https泰涂。如圖:
而如果我們沒有啟用HSTS,而是直接請(qǐng)求站點(diǎn)的話辐怕,那么服務(wù)器會(huì)返回一個(gè)302/301的狀態(tài)碼然后要求客戶端重定向到443端口逼蒙,然后重新以https向服務(wù)器發(fā)起請(qǐng)求。
DNS解析獲取ip地址
根據(jù)URL寄疏,會(huì)開始按照下面的流程查詢是牢,獲取域名對(duì)應(yīng)的IP地址
- 首先會(huì)查詢本機(jī)的host文件,如果獲取到ip則直接返回陕截,如果沒有則繼續(xù)往下查找
- 向本地DNS緩存查詢驳棱,如果查詢到了則返回,沒有則開始向DNS服務(wù)器查詢农曲,而DNS服務(wù)器的ip地址在我們鏈接了網(wǎng)絡(luò)之后本機(jī)就會(huì)有這個(gè)地址了社搅。
- 如果DNS服務(wù)器中沒有查詢到,那么就會(huì)開啟一個(gè)遞歸查詢
- 先向.root服務(wù)器查詢乳规,.root會(huì)返回 .com的ip地址
- 然后向.com服務(wù)器查詢形葬,.com 會(huì)返回 baidu.com的ip地址
- 然后向baidu.com服務(wù)器查詢,baidu.com會(huì)返回 www.baidu.com的ip地址
- 然后www.baidu.com會(huì)返回ip地址,然后本機(jī)會(huì)把ip地址緩存到本地
上圖幫助理解:
RAP協(xié)議解析獲取MAC地址
因?yàn)槲覀冎滥旱模瑱C(jī)器之間的通訊實(shí)際上是網(wǎng)卡之間的通訊笙以,而網(wǎng)卡之間通訊實(shí)際上是通過MAC地址進(jìn)行通訊的。而ARP協(xié)議就是用來通過IP地址解析出MAC地址的
- 主機(jī)回向本機(jī)緩存的ARP協(xié)議表查詢是否有對(duì)應(yīng)的MAC地址冻辩,如果沒有則會(huì)向網(wǎng)絡(luò)發(fā)起一個(gè)廣播(Rap Request)猖腕,網(wǎng)絡(luò)上的其他主機(jī)不會(huì)作出回應(yīng),只有目標(biāo)地址的主機(jī)會(huì)以單播的形式作出回應(yīng)微猖,并且?guī)献约旱?strong>ip和MAC谈息。瀏覽器會(huì)把這個(gè)IP和MAC緩存起來缘屹,同樣的目標(biāo)主機(jī)也會(huì)把我們的IP和MAC緩存起來存放在ARP緩存表里面凛剥。在接下來的一段時(shí)間內(nèi),將不會(huì)再重新請(qǐng)求(TTL)
- 最后會(huì)把這個(gè)MAC地址寫進(jìn)請(qǐng)求幀中
瀏覽器的強(qiáng)緩存或者協(xié)商緩存的觸發(fā)
在我們一切就緒之后轻姿,我們會(huì)開始向服務(wù)器發(fā)送請(qǐng)求犁珠。也就是所謂的瀏覽器和服務(wù)器之間的應(yīng)答逻炊,即瀏覽器向服務(wù)器發(fā)起一次HTTP請(qǐng)求,而在這一步中我們或?yàn)g覽器本身會(huì)存在一種緩存機(jī)制
- 強(qiáng)緩存
- 協(xié)商緩存
在正式講解之前犁享,我們先上一張圖余素。
而執(zhí)行強(qiáng)緩存和協(xié)商緩存,分別是通過不同的標(biāo)識(shí)符來判斷的炊昆。他們的執(zhí)行順序是
(Expires > Cache-Control > Etag/If-None-Match > Last-Modified/If-Modified-Since)
首先瀏覽器會(huì)先執(zhí)行強(qiáng)緩存桨吊,強(qiáng)緩存的過程是:
首先瀏覽器會(huì)先查看緩存中的標(biāo)識(shí)符(Expires / Cache-Control)這兩個(gè)標(biāo)識(shí)符分別存的都是時(shí)間,不過有一些不同凤巨,Expires的值是一個(gè)具體的日期视乐,而Cache-Control的值則是一個(gè)固定的時(shí)間例如Max-age。
瀏覽器在獲取到了標(biāo)識(shí)符之后敢茁,判斷是否已經(jīng)過期佑淀,如果沒過期則直接返回?cái)?shù)據(jù),然后進(jìn)行下一步
2.1 而如果過期了彰檬,則向服務(wù)器發(fā)起http請(qǐng)求 (這個(gè)時(shí)候?qū)?huì)執(zhí)行的是協(xié)商緩存)伸刃。然后一切順利的話,服務(wù)器會(huì)返回標(biāo)識(shí)符和數(shù)據(jù)逢倍,然后瀏覽器再把他們緩存起來
2.2 而如果緩存中沒有標(biāo)識(shí)符也沒有數(shù)據(jù)緩存捧颅,則瀏覽器也會(huì)直接向服務(wù)器發(fā)起http請(qǐng)求,之后也和上面一樣较雕,把結(jié)果緩存起來隘道。(第一次請(qǐng)求)
一切順利的話,會(huì)有以下的效果:
其中郎笆,from memory cache意思是緩存來自內(nèi)存, 如果是from disk cache 則標(biāo)識(shí)緩存來自硬盤
而如果強(qiáng)緩存失效也就是上面的2.1谭梗,那么瀏覽器會(huì)攜帶者標(biāo)識(shí)符,向服務(wù)器發(fā)起請(qǐng)求宛蚓,服務(wù)器會(huì)根據(jù)瀏覽器攜帶過來的標(biāo)識(shí)符判斷是否使用緩存激捏,而這個(gè)過程就是協(xié)商緩存
協(xié)商緩存會(huì)有以下情況:
-
協(xié)商緩存生效,返回響應(yīng)碼304凄吏,瀏覽器根據(jù)304的響應(yīng)碼直接獲取緩存中的數(shù)據(jù)远舅,并且把新的緩存標(biāo)識(shí)也緩存到瀏覽器緩存中。
image -
協(xié)商緩存沒生效痕钢,則返回響應(yīng)碼200图柏,并且返回請(qǐng)求的結(jié)果
image
其實(shí)協(xié)商緩存的過程,請(qǐng)求都會(huì)發(fā)送到服務(wù)器任连。只是服務(wù)器會(huì)根據(jù)緩存標(biāo)識(shí)判斷數(shù)據(jù)是否已失效蚤吹,如果失效了則重新進(jìn)行查詢,然后返回最新的數(shù)據(jù),如果沒有失效裁着,則通知瀏覽器直接取緩存中的數(shù)據(jù)繁涂。
協(xié)商緩存使用的標(biāo)識(shí)符主要是(Last-Modified/If-since-Modified 和 Etag/If-None-Match)
Last-Modified的值是服務(wù)器響應(yīng)請(qǐng)求時(shí),返回該資源文件在服務(wù)器最后被修改的時(shí)間二驰,在響應(yīng)報(bào)文中的字段是:
last-modified: Web, 20 Mar 2020 10:37:56 GTM
而瀏覽器再次發(fā)起請(qǐng)求得時(shí)候以If-Since-Modified的字段去攜帶這個(gè)值扔罪,并且返回后服務(wù)器。之后服務(wù)器會(huì)把這個(gè)值的時(shí)間拿去和文件的更新時(shí)間作對(duì)比桶雀。再按情況返回不同的響應(yīng)碼
而如果我們?cè)O(shè)置了Etag/If-None-Match矿酵。那么會(huì)優(yōu)先執(zhí)行這個(gè)標(biāo)識(shí)符,而這個(gè)標(biāo)識(shí)符的其實(shí)存儲(chǔ)的是文件的一個(gè)唯一標(biāo)識(shí)符矗积,服務(wù)器會(huì)根據(jù)這個(gè)唯一標(biāo)識(shí)符是否一致去判斷文件是否有變更坏瘩。
到這里瀏覽器的緩存就走完了。然后接下來漠魏,假設(shè)我們成功獲取到了服務(wù)器返回的數(shù)據(jù)倔矾。瀏覽器開始解析我們從網(wǎng)絡(luò)上請(qǐng)求下來的數(shù)據(jù)(假設(shè)是一個(gè)html文件)
瀏覽器進(jìn)程對(duì)請(qǐng)求返回的數(shù)據(jù)的解析
首先,瀏覽器的network thread 會(huì)根據(jù)響應(yīng)報(bào)文的Content-Type判斷響應(yīng)主體的媒體類型柱锹,如果返回的是一個(gè)HTML則會(huì)把數(shù)據(jù)交給Render process來進(jìn)行下一步的處理哪自,而如果返回的是一個(gè)zip的文件或者其他,會(huì)把相關(guān)數(shù)據(jù)傳輸給下載管理器
與此同時(shí)禁熏。瀏覽器還會(huì)進(jìn)行Safe Browsing安全檢查壤巷,如果域名或者請(qǐng)求的內(nèi)容匹配到的是已知的惡意站點(diǎn),那么瀏覽器會(huì)展示一個(gè)警告的頁面瞧毙。除此之外網(wǎng)絡(luò)線程還會(huì)做CORB檢查胧华,也就是跨域檢查(即對(duì)比Origin的域名和Acess-Control-Allow的值看是否是一致
假設(shè)我們獲取到的資源是一個(gè)HTML文件,然后瀏覽器會(huì)把HTML文件交給渲染進(jìn)程
渲染進(jìn)程的組成是:
- 一個(gè)主線程(main thread)
- 多個(gè)工作線程(work thread)
- 一個(gè)合成器線程(compositor thread)
- 多個(gè)光柵化線程(raster thread)
待續(xù)....