在瀏覽器輸入url后發(fā)生了什么

著名前端面試題:
一個(gè)頁(yè)面從輸入 URL 到頁(yè)面加載顯示完成,這個(gè)過(guò)程中都發(fā)生了什么?
主要包括以下幾個(gè)基本步驟:

  1. 瀏覽器的地址欄輸入U(xiǎn)RL并按下回車(chē)。
  2. 瀏覽器查找當(dāng)前URL是否存在緩存,并比較緩存是否過(guò)期。
  3. DNS解析URL對(duì)應(yīng)的IP。
  4. 根據(jù)IP建立TCP連接(三次握手)。
  5. HTTP發(fā)起請(qǐng)求。
  6. 服務(wù)器處理請(qǐng)求,瀏覽器接收HTTP響應(yīng)。
  7. 渲染頁(yè)面,構(gòu)建DOM樹(shù)。
  8. 關(guān)閉TCP連接(四次揮手)。
    接下來(lái)對(duì)其中幾個(gè)步驟展開(kāi)說(shuō)一下

1. URL

輸入U(xiǎn)RL后,會(huì)進(jìn)行解析(URL的本質(zhì)就是統(tǒng)一資源定位符)
URL一般包括幾大部分:

  • protocol,協(xié)議頭,譬如有http,加密的https,ftp等
  • host,主機(jī)域名或IP地址
  • port,端口號(hào)(通常端口號(hào)不常見(jiàn)是因?yàn)榇蟛糠值亩际鞘褂媚J(rèn)的端口所以隱藏,如HTTP默認(rèn)端口80,HTTPS默認(rèn)端口443。)
  • path,目錄路徑
  • query,即查詢(xún)參數(shù)
  • fragment,即#后的hash值,一般用來(lái)定位到某個(gè)位置

其他面試官可能問(wèn)的知識(shí)點(diǎn):同源策略,跨域的問(wèn)題(待補(bǔ)充)

2.緩存

根據(jù)下圖的邏輯,判斷是直接使用緩存內(nèi)容還是重新向服務(wù)器請(qǐng)求資源


緩存.png

3.DNS域名解析

我們知道在地址欄輸入的域名并不是最后資源所在的真實(shí)位置,域名只是與IP地址的一個(gè)映射。網(wǎng)絡(luò)服務(wù)器的IP地址那么多,我們不可能去記一串串的數(shù)字,因此域名就產(chǎn)生了,域名解析的過(guò)程實(shí)際是將域名還原為IP地址的過(guò)程。
首先瀏覽器先檢查本地hosts文件是否有這個(gè)網(wǎng)址映射關(guān)系,如果有就調(diào)用這個(gè)IP地址映射,完成域名解析。
如果沒(méi)找到則會(huì)查找本地DNS解析器緩存,如果查找到則返回。
如果還是沒(méi)有找到則會(huì)查找本地DNS服務(wù)器,如果查找到則返回。
最后迭代查詢(xún),按根域服務(wù)器 ->頂級(jí)域,.com->第二層域,baidu.com ->子域,www.baidu.com的順序找到IP地址。

4.TCP連接

在通過(guò)第一步的DNS域名解析后,獲取到了服務(wù)器的IP地址,在獲取到IP地址后,便會(huì)開(kāi)始建立一次連接,這是由TCP協(xié)議完成的,主要通過(guò)三次握手進(jìn)行連接。

  • 第一次握手: 建立連接時(shí),客戶(hù)端發(fā)送syn包(seq=x)到服務(wù)器,并進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn);
  • 第二次握手: 服務(wù)器收到syn包,必須確認(rèn)客戶(hù)的SYN(ack=x+1),同時(shí)自己也發(fā)送一個(gè)SYN包(seq=y),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);
  • 第三次握手: 客戶(hù)端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=y+1),此包發(fā)送完畢,客戶(hù)端和服務(wù)器進(jìn)入ESTABLISHED(TCP連接成功)狀態(tài),完成三次握手。

完成三次握手,客戶(hù)端與服務(wù)器開(kāi)始傳送數(shù)據(jù)。

TCP三次握手.png

5. 瀏覽器向服務(wù)器發(fā)送HTTP請(qǐng)求

完整的HTTP請(qǐng)求包含請(qǐng)求起始行、請(qǐng)求頭部、請(qǐng)求主體三部分。


http請(qǐng)求.png

常用的請(qǐng)求頭部(部分)

Accept: 接收類(lèi)型,表示瀏覽器支持的MIME類(lèi)型
(對(duì)標(biāo)服務(wù)端返回的Content-Type)
Accept-Encoding:瀏覽器支持的壓縮類(lèi)型,如gzip等,超出類(lèi)型不能接收
Content-Type:客戶(hù)端發(fā)送出去實(shí)體內(nèi)容的類(lèi)型
Cache-Control: 指定請(qǐng)求和響應(yīng)遵循的緩存機(jī)制,如no-cache
If-Modified-Since:對(duì)應(yīng)服務(wù)端的Last-Modified,用來(lái)匹配看文件是否變動(dòng),只能精確到1s之內(nèi),http1.0中
Expires:緩存控制,在這個(gè)時(shí)間內(nèi)不會(huì)請(qǐng)求,直接使用緩存,http1.0,而且是服務(wù)端時(shí)間
Max-age:代表資源在本地緩存多少秒,有效時(shí)間內(nèi)不會(huì)請(qǐng)求,而是使用緩存,http1.1中
If-None-Match:對(duì)應(yīng)服務(wù)端的ETag,用來(lái)匹配文件內(nèi)容是否改變(非常精確),http1.1中
Cookie: 有cookie并且同域訪(fǎng)問(wèn)時(shí)會(huì)自動(dòng)帶上
Connection: 當(dāng)瀏覽器與服務(wù)器通信時(shí)對(duì)于長(zhǎng)連接如何進(jìn)行處理,如keep-alive
Host:請(qǐng)求的服務(wù)器URL
Origin:最初的請(qǐng)求是從哪里發(fā)起的(只會(huì)精確到端口),Origin比Referer更尊重隱私
Referer:該頁(yè)面的來(lái)源URL(適用于所有類(lèi)型的請(qǐng)求,會(huì)精確到詳細(xì)頁(yè)面地址,csrf攔截常用到這個(gè)字段)
User-Agent:用戶(hù)客戶(hù)端的一些必要信息,如UA頭部等

6. 瀏覽器接收服務(wù)器的響

服務(wù)器在收到瀏覽器發(fā)送的HTTP請(qǐng)求之后,會(huì)將收到的HTTP報(bào)文封裝成HTTP的Request對(duì)象,并通過(guò)不同的Web服務(wù)器進(jìn)行處理,處理完的結(jié)果以HTTP的Response對(duì)象返回,主要包括狀態(tài)碼,響應(yīng)頭,響應(yīng)報(bào)文三個(gè)部分。
狀態(tài)碼主要包括以下部分

  • 1xx:指示信息–表示請(qǐng)求已接收,繼續(xù)處理。
  • 2xx:成功–表示請(qǐng)求已被成功接收、理解、接受。
  • 3xx:重定向–要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作。
  • 4xx:客戶(hù)端錯(cuò)誤–請(qǐng)求有語(yǔ)法錯(cuò)誤或請(qǐng)求無(wú)法實(shí)現(xiàn)。
  • 5xx:服務(wù)器端錯(cuò)誤–服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求。
    響應(yīng)頭主要由Cache-Control、 Connection、Date、Pragma等組成。
    響應(yīng)體為服務(wù)器返回給瀏覽器的信息,主要由HTML,css,js,圖片文件組成。
    常用的響應(yīng)頭部(部分):
Access-Control-Allow-Headers: 服務(wù)器端允許的請(qǐng)求Headers
Access-Control-Allow-Methods: 服務(wù)器端允許的請(qǐng)求方法
Access-Control-Allow-Origin: 服務(wù)器端允許的請(qǐng)求Origin頭部(譬如為*)
Content-Type:服務(wù)端返回的實(shí)體內(nèi)容的類(lèi)型
Date:數(shù)據(jù)從服務(wù)器發(fā)送的時(shí)間
Cache-Control:告訴瀏覽器或其他客戶(hù),什么環(huán)境可以安全的緩存文檔
Last-Modified:請(qǐng)求資源的最后修改時(shí)間
Expires:應(yīng)該在什么時(shí)候認(rèn)為文檔已經(jīng)過(guò)期,從而不再緩存它
Max-age:客戶(hù)端的本地資源應(yīng)該緩存多少秒,開(kāi)啟了Cache-Control后有效
ETag:請(qǐng)求變量的實(shí)體標(biāo)簽的當(dāng)前值
Set-Cookie:設(shè)置和頁(yè)面關(guān)聯(lián)的cookie,服務(wù)器通過(guò)這個(gè)頭部把cookie傳給客戶(hù)端
Keep-Alive:如果客戶(hù)端有keep-alive,服務(wù)端也會(huì)有響應(yīng)(如timeout=38)
Server:服務(wù)器的一些相關(guān)信息

如下圖是對(duì)某請(qǐng)求的http報(bào)文結(jié)構(gòu)的簡(jiǎn)要分析


image.png

7. 頁(yè)面渲染

前面有提到http交互,那么接下來(lái)就是瀏覽器獲取到html,然后解析,渲染

  1. 解析HTML,構(gòu)建DOM樹(shù)
  2. 解析CSS,生成CSS規(guī)則樹(shù)
  3. 合并DOM樹(shù)和CSS規(guī)則,生成render樹(shù)
  4. 布局render樹(shù)(Layout/reflow),負(fù)責(zé)各元素尺寸、位置的計(jì)算
  5. 繪制render樹(shù)(paint),繪制頁(yè)面像素信息
  6. 瀏覽器會(huì)將各層的信息發(fā)送給GPU,GPU會(huì)將各層合成(composite),顯示在屏幕上
    如下圖:


    頁(yè)面渲染.png

    DOM樹(shù).png

    CSSOM樹(shù).png
  • 在瀏覽器還沒(méi)接收到完整的 HTML 文件時(shí),它就開(kāi)始渲染頁(yè)面了,在遇到外部鏈入的腳本標(biāo)簽或樣式標(biāo)簽或圖片時(shí),會(huì)再次發(fā)送 HTTP 請(qǐng)求重復(fù)上述的步驟。在收到 CSS 文件后會(huì)對(duì)已經(jīng)渲染的頁(yè)面重新渲染,加入它們應(yīng)有的樣式,圖片文件加載完立刻顯示在相應(yīng)位置。在這一過(guò)程中可能會(huì)觸發(fā)頁(yè)面的重繪或重排。這里就涉及了兩個(gè)重要概念:Reflow和Repaint。
  • Reflow,也稱(chēng)作Layout,中文叫回流,一般意味著元素的內(nèi)容、結(jié)構(gòu)、位置或尺寸發(fā)生了變化,需要重新計(jì)算樣式和渲染樹(shù),這個(gè)過(guò)程稱(chēng)為Reflow。
  • Repaint,中文重繪,意味著元素發(fā)生的改變只是影響了元素的一些外觀之類(lèi)的時(shí)候(例如,背景色,邊框顏色,文字顏色等),此時(shí)只需要應(yīng)用新樣式繪制這個(gè)元素就OK了,這個(gè)過(guò)程稱(chēng)為Repaint。
  • 所以說(shuō)Reflow的成本比Repaint的成本高得多的多。DOM樹(shù)里的每個(gè)結(jié)點(diǎn)都會(huì)有reflow方法,一個(gè)結(jié)點(diǎn)的reflow很有可能導(dǎo)致子結(jié)點(diǎn),甚至父點(diǎn)以及同級(jí)結(jié)點(diǎn)的reflow。

8. 關(guān)閉TCP連接或繼續(xù)保持連接

通過(guò)四次揮手關(guān)閉連接(FIN ACK, ACK, FIN ACK, ACK)。


關(guān)閉TCP連接-四次揮手.png
  • 第一次揮手是瀏覽器發(fā)完數(shù)據(jù)后,發(fā)送FIN請(qǐng)求斷開(kāi)連接。
  • 第二次揮手是服務(wù)器發(fā)送ACK表示同意,如果在這一次服務(wù)器也發(fā)送FIN請(qǐng)求斷開(kāi)連接似乎也沒(méi)有不妥,但考慮到服務(wù)器可能還有數(shù)據(jù)要發(fā)送,所以服務(wù)器發(fā)送FIN應(yīng)該放在第三次揮手中。
  • 這樣瀏覽器需要返回ACK表示同意,也就是第四次揮手。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容