復習一下:從URL輸入到頁面展現(xiàn)到底發(fā)生什么?
前言
打開瀏覽器從輸入網(wǎng)址到網(wǎng)頁呈現(xiàn)在大家面前,背后到底發(fā)生了什么?經(jīng)歷怎么樣的一個過程?先給大家來張總體流程圖,具體步驟請看下文分解!
總體來說分為以下幾個過程:
DNS 解析:將域名解析成 IP 地址
TCP 連接:TCP 三次握手
發(fā)送 HTTP 請求
服務器處理請求并返回 HTTP 報文
瀏覽器解析渲染頁面
斷開連接:TCP 四次揮手
一、URL 到底是啥
URL(Uniform Resource Locator),統(tǒng)一資源定位符,用于定位互聯(lián)網(wǎng)上資源,俗稱網(wǎng)址。比如 http://www.w3school.com.cn/html/index.asp,遵守以下的語法規(guī)則:
scheme://host.domain:port/path/filename各部分解釋如下:scheme - 定義因特網(wǎng)服務的類型。常見的協(xié)議有 http、https、ftp、file,其中最常見的類型是 http,而 https 則是進行加密的網(wǎng)絡傳輸。host - 定義域主機(http 的默認主機是 www) domain - 定義因特網(wǎng)域名,比如 w3school.com.cn port - 定義主機上的端口號(http 的默認端口號是 80) path - 定義服務器上的路徑(如果省略,則文檔必須位于網(wǎng)站的根目錄中)。filename - 定義文檔/資源的名稱
二、域名解析(DNS)
在瀏覽器輸入網(wǎng)址后,首先要經(jīng)過域名解析,因為瀏覽器并不能直接通過域名找到對應的服務器,而是要通過 IP 地址。大家這里或許會有個疑問----計算機既可以被賦予 IP 地址,也可以被賦予主機名和域名。比如 www.hackr.jp。那怎么不一開始就賦予個 IP 地址?這樣就可以省去解析麻煩。我們先來了解下什么是 IP 地址
1.IP 地址
IP 地址是指互聯(lián)網(wǎng)協(xié)議地址,是 IP Address 的縮寫。IP 地址是 IP 協(xié)議提供的一種統(tǒng)一的地址格式,它為互聯(lián)網(wǎng)上的每一個網(wǎng)絡和每一臺主機分配一個邏輯地址,以此來屏蔽物理地址的差異。IP 地址是一個 32 位的二進制數(shù),比如 127.0.0.1 為本機 IP。域名就相當于 IP 地址喬裝打扮的偽裝者,帶著一副面具。它的作用就是便于記憶和溝通的一組服務器的地址。用戶通常使用主機名或域名來訪問對方的計算機,而不是直接通過 IP 地址訪問。因為與 IP 地址的一組純數(shù)字相比,用字母配合數(shù)字的表示形式來指定計算機名更符合人類的記憶習慣。但要讓計算機去理解名稱,相對而言就變得困難了。因為計算機更擅長處理一長串數(shù)字。為了解決上述的問題,DNS 服務應運而生。
2.什么是域名解析
DNS 協(xié)議提供通過域名查找 IP 地址,或逆向從 IP 地址反查域名的服務。DNS 是一個網(wǎng)絡服務器,我們的域名解析簡單來說就是在 DNS 上記錄一條信息記錄。
例如 baidu.com ?220.114.23.56(服務器外網(wǎng)IP地址)80(服務器端口號)
3. 瀏覽器如何通過域名去查詢 URL 對應的 IP 呢
瀏覽器緩存:瀏覽器會按照一定的頻率緩存 DNS 記錄。
操作系統(tǒng)緩存:如果瀏覽器緩存中找不到需要的 DNS 記錄,那就去操作系統(tǒng)中找。
路由緩存:路由器也有 DNS 緩存。
ISP 的 DNS 服務器:ISP 是互聯(lián)網(wǎng)服務提供商(Internet Service Provider)的簡稱,ISP 有專門的 DNS 服務器應對 DNS 查詢請求。
根服務器:ISP 的 DNS 服務器還找不到的話,它就會向根服務器發(fā)出請求,進行遞歸查詢(DNS 服務器先問根域名服務器.com 域名服務器的 IP 地址,然后再問.baidu 域名服務器,依次類推)

4. 小結
瀏覽器通過向 DNS 服務器發(fā)送域名,DNS 服務器查詢到與域名相對應的 IP 地址,然后返回給瀏覽器,瀏覽器再將 IP 地址打在協(xié)議上,同時請求參數(shù)也會在協(xié)議搭載,然后一并發(fā)送給對應的服務器。接下來介紹向服務器發(fā)送 HTTP 請求階段,HTTP 請求分為三個部分:TCP 三次握手、http 請求響應信息、關閉 TCP 連接。

三、TCP 三次握手
在客戶端發(fā)送數(shù)據(jù)之前會發(fā)起 TCP 三次握手用以同步客戶端和服務端的序列號和確認號,并交換 TCP 窗口大小信息。
1.TCP 三次握手的過程如下:
客戶端發(fā)送一個帶 SYN=1,Seq=X 的數(shù)據(jù)包到服務器端口(第一次握手,由瀏覽器發(fā)起,告訴服務器我要發(fā)送請求了)
服務器發(fā)回一個帶 SYN=1, ACK=X+1, Seq=Y 的響應包以示傳達確認信息(第二次握手,由服務器發(fā)起,告訴瀏覽器我準備接受了,你趕緊發(fā)送吧)
客戶端再回傳一個帶 ACK=Y+1, Seq=Z 的數(shù)據(jù)包,代表“握手結束”(第三次握手,由瀏覽器發(fā)送,告訴服務器,我馬上就發(fā)了,準備接受吧)
2.為啥需要三次握手
謝希仁著《計算機網(wǎng)絡》中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產(chǎn)生錯誤”。
四、發(fā)送 HTTP 請求
TCP 三次握手結束后,開始發(fā)送 HTTP 請求報文。請求報文由請求行(request line)、請求頭(header)、請求體四個部分組成,如下圖所示:
1.請求行包含請求方法、URL、協(xié)議版本
請求方法包含 8 種:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
URL 即請求地址,由 <協(xié)議>://<主機>:<端口>/<路徑>?<參數(shù)> 組成
協(xié)議版本即 http 版本號
POST /chapter17/user.html HTTP/1.1
以上代碼中“POST”代表請求方法,“/chapter17/user.html”表示 URL,“HTTP/1.1”代表協(xié)議和協(xié)議的版本?,F(xiàn)在比較流行的是 Http1.1 版本
2.請求頭包含請求的附加信息,由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。
請求頭部通知服務器有關于客戶端請求的信息。它包含許多有關的客戶端環(huán)境和請求正文的有用信息。其中比如:Host,表示主機名,虛擬主機;Connection,HTTP/1.1 增加的,使用 keepalive,即持久連接,一個連接可以發(fā)多個請求;User-Agent,請求發(fā)出者,兼容性以及定制化需求。
3.請求體,可以承載多個請求參數(shù)的數(shù)據(jù),包含回車符、換行符和請求數(shù)據(jù),并不是所有請求都具有請求數(shù)據(jù)。
name=tom&password=1234&realName=tomson
上面代碼,承載著 name、password、realName 三個請求參數(shù)。
五、服務器處理請求并返回 HTTP 報文
1. 服務器
服務器是網(wǎng)絡環(huán)境中的高性能計算機,它偵聽網(wǎng)絡上的其他計算機(客戶機)提交的服務請求,并提供相應的服務,比如網(wǎng)頁服務、文件下載服務、郵件服務、視頻服務。而客戶端主要的功能是瀏覽網(wǎng)頁、看視頻、聽音樂等等,兩者截然不同。每臺服務器上都會安裝處理請求的應用——web server。常見的 web server 產(chǎn)品有 apache、nginx、IIS 或 Lighttpd 等。web server 擔任管控的角色,對于不同用戶發(fā)送的請求,會結合配置文件,把不同請求委托給服務器上處理相應請求的程序進行處理(例如 CGI 腳本,JSP 腳本,servlets,ASP 腳本,服務器端 JavaScript,或者一些其它的服務器端技術等),然后返回后臺程序處理產(chǎn)生的結果作為響應。
2.MVC 后臺處理階段
后臺開發(fā)現(xiàn)在有很多框架,但大部分都還是按照 MVC 設計模式進行搭建的。MVC 是一個設計模式,將應用程序分成三個核心部件:模型(model)-- 視圖(view)--控制器(controller),它們各自處理自己的任務,實現(xiàn)輸入、處理和輸出的分離。
1、視圖(view)
它是提供給用戶的操作界面,是程序的外殼。
2、模型(model)
模型主要負責數(shù)據(jù)交互。在 MVC 的三個部件中,模型擁有最多的處理任務。一個模型能為多個視圖提供數(shù)據(jù)。
3、控制器(controller)
它負責根據(jù)用戶從"視圖層"輸入的指令,選取"模型層"中的數(shù)據(jù),然后對其進行相應的操作,產(chǎn)生最終結果。控制器屬于管理者角色,從視圖接收請求并決定調用哪個模型構件去處理請求,然后再確定用哪個視圖來顯示模型處理返回的數(shù)據(jù)。這三層是緊密聯(lián)系在一起的,但又是互相獨立的,每一層內部的變化不影響其他層。每一層都對外提供接口(Interface),供上面一層調用。至于這一階段發(fā)生什么?簡而言之,首先瀏覽器發(fā)送過來的請求先經(jīng)過控制器,控制器進行邏輯處理和請求分發(fā),接著會調用模型,這一階段模型會獲取 redis db 以及 MySQL 的數(shù)據(jù),獲取數(shù)據(jù)后將渲染好的頁面,響應信息會以響應報文的形式返回給客戶端,最后瀏覽器通過渲染引擎將網(wǎng)頁呈現(xiàn)在用戶面前。
3.http 響應報文
響應報文由響應行(request line)、響應頭部(header)、響應主體三個部分組成。如下圖所示:
(1) 響應行包含:協(xié)議版本,狀態(tài)碼,狀態(tài)碼描述
狀態(tài)碼規(guī)則如下:1xx:指示信息--表示請求已接收,繼續(xù)處理。2xx:成功--表示請求已被成功接收、理解、接受。3xx:重定向--要完成請求必須進行更進一步的操作。4xx:客戶端錯誤--請求有語法錯誤或請求無法實現(xiàn)。5xx:服務器端錯誤--服務器未能實現(xiàn)合法的請求。
(2) 響應頭部包含響應報文的附加信息,由 名/值 對組成
(3) 響應主體包含回車符、換行符和響應返回數(shù)據(jù),并不是所有響應報文都有響應數(shù)據(jù)
六、瀏覽器解析渲染頁面
瀏覽器拿到響應文本 HTML 后,接下來介紹下瀏覽器渲染機制

瀏覽器解析渲染頁面分為一下五個步驟:
根據(jù) HTML 解析出 DOM 樹
根據(jù) CSS 解析生成 CSS 規(guī)則樹
結合 DOM 樹和 CSS 規(guī)則樹,生成渲染樹
根據(jù)渲染樹計算每一個節(jié)點的信息
根據(jù)計算好的信息繪制頁面
1.根據(jù) HTML 解析 DOM 樹
根據(jù) HTML 的內容,將標簽按照結構解析成為 DOM 樹,DOM 樹解析的過程是一個深度優(yōu)先遍歷。即先構建當前節(jié)點的所有子節(jié)點,再構建下一個兄弟節(jié)點。
在讀取 HTML 文檔,構建 DOM 樹的過程中,若遇到 script 標簽,則 DOM 樹的構建會暫停,直至腳本執(zhí)行完畢。
2.根據(jù) CSS 解析生成 CSS 規(guī)則樹
解析 CSS 規(guī)則樹時 js 執(zhí)行將暫停,直至 CSS 規(guī)則樹就緒。
瀏覽器在 CSS 規(guī)則樹生成之前不會進行渲染。
3.結合 DOM 樹和 CSS 規(guī)則樹,生成渲染樹
DOM 樹和 CSS 規(guī)則樹全部準備好了以后,瀏覽器才會開始構建渲染樹。
精簡 CSS 并可以加快 CSS 規(guī)則樹的構建,從而加快頁面相應速度。
4.根據(jù)渲染樹計算每一個節(jié)點的信息(布局)
布局:通過渲染樹中渲染對象的信息,計算出每一個渲染對象的位置和尺寸
回流:在布局完成后,發(fā)現(xiàn)了某個部分發(fā)生了變化影響了布局,那就需要倒回去重新渲染。
5.根據(jù)計算好的信息繪制頁面
繪制階段,系統(tǒng)會遍歷呈現(xiàn)樹,并調用呈現(xiàn)器的“paint”方法,將呈現(xiàn)器的內容顯示在屏幕上。
重繪:某個元素的背景顏色,文字顏色等,不影響元素周圍或內部布局的屬性,將只會引起瀏覽器的重繪。
回流:某個元素的尺寸發(fā)生了變化,則需重新計算渲染樹,重新渲染。
七、斷開連接
當數(shù)據(jù)傳送完畢,需要斷開 tcp 連接,此時發(fā)起 tcp 四次揮手。
發(fā)起方向被動方發(fā)送報文,F(xiàn)in、Ack、Seq,表示已經(jīng)沒有數(shù)據(jù)傳輸了。并進入 FINWAIT1 狀態(tài)。(第一次揮手:由瀏覽器發(fā)起的,發(fā)送給服務器,我請求報文發(fā)送完了,你準備關閉吧)
被動方發(fā)送報文,Ack、Seq,表示同意關閉請求。此時主機發(fā)起方進入 FINWAIT2 狀態(tài)。(第二次揮手:由服務器發(fā)起的,告訴瀏覽器,我請求報文接受完了,我準備關閉了,你也準備吧)
被動方向發(fā)起方發(fā)送報文段,F(xiàn)in、Ack、Seq,請求關閉連接。并進入 LAST_ACK 狀態(tài)。(第三次揮手:由服務器發(fā)起,告訴瀏覽器,我響應報文發(fā)送完了,你準備關閉吧)
發(fā)起方向被動方發(fā)送報文段,Ack、Seq。然后進入等待 TIME_WAIT 狀態(tài)。被動方收到發(fā)起方的報文段以后關閉連接。發(fā)起方等待一定時間未收到回復,則正常關閉。(第四次揮手:由瀏覽器發(fā)起,告訴服務器,我響應報文接受完了,我準備關閉了,你也準備吧)
參考文章
? ? 從輸入頁面地址到展示頁面信息都發(fā)生了些什么?
? ? 前端經(jīng)典面試題: 從輸入 URL 到頁面加載發(fā)生了什么?
? ? TCP 的三次握手四次揮手
? ? 訪問 Web,tcp 傳輸全過程(三次握手、請求、數(shù)據(jù)傳輸、四次揮手)
? ? 瀏覽器發(fā)送 http 請求過程分析
? ? 謝希仁著《計算機網(wǎng)絡》第四版
? ? 圖解 http
