一個頁面從輸入 URL 到頁面加載顯示完成,這個過程中都發(fā)生了什么?

  1. DNS解析

  2. TCP連接

  3. 發(fā)送HTTP請求

  4. 服務(wù)器處理請求并返回HTTP報文

  5. 瀏覽器解析渲染頁面

  6. 連接結(jié)束

1DNS解析

DNS解析的過程就是尋找哪臺機器上有你需要資源的過程。DNS解析,它實際上充當(dāng)了一個翻譯的角色,實現(xiàn)了網(wǎng)址到IP地址的轉(zhuǎn)換。

輸入www.google.com首先在本地域名服務(wù)器中查詢IP地址,如果沒有找到的情況下,本地域名服務(wù)器會向根域名服務(wù)器發(fā)送一個請求,如果根域名服務(wù)器也不存在該域名時,本地域名會向com頂級域名服務(wù)器發(fā)送一個請求,依次類推下去。直到最后本地域名服務(wù)器得到google的IP地址并把它緩存到本地,供下次查詢使用。

2TCP連接

TCP三次握手
(1)第一次握手:Client將標(biāo)志位SYN置為1,隨機產(chǎn)生一個值seq=J,并將該數(shù)據(jù)包發(fā)送給Server,Client進入SYN_SENT狀態(tài),等待Server確認。

(2)第二次握手:Server收到數(shù)據(jù)包后由標(biāo)志位SYN=1知道Client請求建立連接,Server將標(biāo)志位SYN和ACK都置為1,ack=J+1,隨機產(chǎn)生一個值seq=K,并將該數(shù)據(jù)包發(fā)送給Client以確認連接請求,Server進入SYN_RCVD狀態(tài)。

(3)第三次握手:Client收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標(biāo)志位ACK置為1,ack=K+1,并將該數(shù)據(jù)包發(fā)送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態(tài),完成三次握手,隨后Client與Server之間可以開始傳輸數(shù)據(jù)了。
簡單來說

  1. 建立連接時,客戶端發(fā)送SYN包(SYN=i)到服務(wù)器,并進入到SYN-SEND狀態(tài),等待服務(wù)器確認

  2. 服務(wù)器收到SYN包,必須確認客戶的SYN(ack=i+1),同時自己也發(fā)送一個SYN包(SYN=k),即SYN+ACK包,此時服務(wù)器進入SYN-RECV狀態(tài)

  3. 客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認報ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進入ESTABLISHED狀態(tài),完成三次握手,客戶端與服務(wù)器開始傳送數(shù)據(jù)。
    TCP四次揮手
    由于TCP連接時全雙工的,因此,每個方向都必須要單獨進行關(guān)閉,這一原則是當(dāng)一方完成數(shù)據(jù)發(fā)送任務(wù)后,發(fā)送一個FIN來終止這一方向的連接,收到一個FIN只是意味著這一方向上沒有數(shù)據(jù)流動了,即不會再收到數(shù)據(jù)了,但是在這個TCP連接上仍然能夠發(fā)送數(shù)據(jù),直到這一方向也發(fā)送了FIN。首先進行關(guān)閉的一方將執(zhí)行主動關(guān)閉,而另一方則執(zhí)行被動關(guān)閉,上圖描述的即是如此。

(1)第一次揮手:Client發(fā)送一個FIN,用來關(guān)閉Client到Server的數(shù)據(jù)傳送,Client進入FIN_WAIT_1狀態(tài)。

(2)第二次揮手:Server收到FIN后,發(fā)送一個ACK給Client,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號),Server進入CLOSE_WAIT狀態(tài)。

(3)第三次揮手:Server發(fā)送一個FIN,用來關(guān)閉Server到Client的數(shù)據(jù)傳送,Server進入LAST_ACK狀態(tài)。

(4)第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態(tài),接著發(fā)送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態(tài),完成四次揮手。

3發(fā)送HTTP請求

發(fā)送HTTP請求的過程就是構(gòu)建HTTP請求報文并通過TCP協(xié)議中發(fā)送到服務(wù)器指定端口(HTTP協(xié)議80/8080, HTTPS協(xié)議443)。
HTTP請求報文是由三部分組成: 請求行, 請求報頭和請求正文。

請求行

Method Request-URL HTTP-Version

GET index.html HTTP/1.1

常用的方法有: GET, POST, PUT, DELETE, OPTIONS, HEAD。

請求報頭

請求報頭允許客戶端向服務(wù)器傳遞請求的附加信息和客戶端自身的信息。
PS: 客戶端不一定特指瀏覽器,有時候也可使用Linux下的CURL命令以及HTTP客戶端測試工具等。
常見的請求報頭有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等。

請求正文

當(dāng)使用POST, PUT等方法時,通常需要客戶端向服務(wù)器傳遞數(shù)據(jù)。這些數(shù)據(jù)就儲存在請求正文中。在請求包頭中有一些與請求正文相關(guān)的信息,例如: 現(xiàn)在的Web應(yīng)用通常采用Rest架構(gòu),請求的數(shù)據(jù)格式一般為json。這時就需要設(shè)置Content-Type: application/json。

服務(wù)器處理請求并返回HTTP報文

自然而然這部分對應(yīng)的就是后端工程師眼中的HTTP。后端從在固定的端口接收到TCP報文開始,這一部分對應(yīng)于編程語言中的socket。它會對TCP連接進行處理,對HTTP協(xié)議進行解析,并按照報文格式進一步封裝成HTTP Request對象,供上層使用。這一部分工作一般是由Web服務(wù)器去進行,我使用過的Web服務(wù)器有Tomcat, Jetty和Netty等等。

HTTP響應(yīng)報文也是由三部分組成: 狀態(tài)碼, 響應(yīng)報頭和響應(yīng)報文。

狀態(tài)碼

狀態(tài)碼是由3位數(shù)組成,第一個數(shù)字定義了響應(yīng)的類別,且有五種可能取值:
1xx:指示信息–表示請求已接收,繼續(xù)處理。
2xx:成功–表示請求已被成功接收、理解、接受。
3xx:重定向–要完成請求必須進行更進一步的操作。
4xx:客戶端錯誤–請求有語法錯誤或請求無法實現(xiàn)。
5xx:服務(wù)器端錯誤–服務(wù)器未能實現(xiàn)合法的請求。
平時遇到比較常見的狀態(tài)碼有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500。

響應(yīng)報頭

常見的響應(yīng)報頭字段有: Server, Connection...。

響應(yīng)報文

服務(wù)器返回給瀏覽器的文本信息,通常HTML, CSS, JS, 圖片等文件就放在這一部分。

瀏覽器解析渲染頁面

瀏覽器在收到HTML,CSS,JS文件后,開始渲染頁面。
瀏覽器是一個邊解析邊渲染的過程。首先瀏覽器解析HTML文件構(gòu)建DOM樹,然后解析CSS文件構(gòu)建渲染樹,等到渲染樹構(gòu)建完成后,瀏覽器開始布局渲染樹并將其繪制到屏幕上。這個過程比較復(fù)雜,涉及到兩個概念: reflow(回流)和repain(重繪)。DOM節(jié)點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等,這個過程稱為relow;當(dāng)盒模型的位置,大小以及其他屬性,如顏色,字體,等確定下來之后,瀏覽器便開始繪制內(nèi)容,這個過程稱為repain。頁面在首次加載時必然會經(jīng)歷reflow和repain。reflow和repain過程是非常消耗性能的,尤其是在移動設(shè)備上,它會破壞用戶體驗,有時會造成頁面卡頓。所以我們應(yīng)該盡可能少的減少reflow和repain。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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