從打開瀏覽器輸入網(wǎng)址, 到頁面呈現(xiàn), 背后發(fā)生了什么? 經(jīng)歷了怎樣的一個過程? 先給大家來張總體的流程圖, 具體步驟請看下文分解.
從URL輸入到頁面呈現(xiàn), 大致分為以下6個步驟:
- DNS解析, 將域名解析成IP地址
- TCP連接: TCP三次握手
- 發(fā)送HTTP請求
- 服務器處理請求并返回HTTP報文
- 瀏覽器解析渲染頁面
- 斷開連接: TCP四次揮手
1. URL是什么?
URL(Uniform Resource Locator),統(tǒng)一資源定位符侣背,用于定位互聯(lián)網(wǎng)上資源哼转,俗稱網(wǎng)址呕诉。
比如 http://www.baidu.com/demo/index.html,遵守以下的語法規(guī)則:
scheme://host.domain:port/path/filename
各部分解釋如下:
- scheme: 定義Internet協(xié)議的類型, 常見的有: http, https, ftp, file, 其中最常見的就是http, 而https則是進行加密的網(wǎng)絡傳輸
- host, 定義域主機(http的默認主機是www)
- domain, 域名, 比如: www.baidu.com
- port: 主機上的端口號(http的默認端口號是80)
- path: 服務器上的路徑(如果省略, 則文檔必須位于網(wǎng)站的根目錄中).
- filename, 定義文檔/資源的名稱
2. 域名解析(DNS)
在瀏覽器輸入網(wǎng)址后, 首先要經(jīng)過域名解析, 因為瀏覽器并不能直接通過域名找到對應的服務器, 而是要通過IP地址.
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地址的一組純數(shù)字相比, 用字母組合配合數(shù)字的表示形式來指定計算機名更符合人類的記憶習慣, 但要讓計算機去理解名稱, 相對而言就變得困難了. 因為計算機更擅長處理一長串數(shù)字. 為了解決上述問題, DNS服務應運而生.
域名解析
DNS協(xié)議提供通過域名查找IP地址, 或逆向從IP地址反查域名的服務. DNS是一個網(wǎng)絡服務器, 我們的域名解析簡單來說就是在DNS上記錄一條信息記錄.
例如 baidu.com 220.114.23.56(服務器外網(wǎng)IP地址)80(服務器端口號)
瀏覽器如何通過域名去查詢URL對應的IP?
- 瀏覽器緩存: 瀏覽器會按照一定的頻率緩存DNS記錄.
- 操作系統(tǒng)緩存: 如果瀏覽器緩存中沒有找到需要的DN記錄, 就會去操作系統(tǒng)中查找
- 路由緩存: 路由器也有DNS緩存
- ISP的DNS服務器: ISP 是互聯(lián)網(wǎng)服務提供商(Internet Service Provider)的簡稱,ISP 有專門的 DNS 服務器應對 DNS 查詢請求揖盘。
- 根服務器: ISP 的 DNS 服務器還找不到的話,它就會向根服務器發(fā)出請求锌奴,進行遞歸查詢(DNS 服務器先問根域名服務器.com 域名服務器的 IP 地址兽狭,然后再問.baidu 域名服務器,依次類推)
瀏覽器通過向DNS服務器發(fā)送域名, DNS服務器查詢到與域名相對應的IP地址, 然后返回給瀏覽器, 瀏覽器再將IP地址打在協(xié)議上, 同時請求參數(shù)也會在協(xié)議中搭載, 然后一并發(fā)送給對應原服務器.
3. TCP三次握手
在客戶端發(fā)送數(shù)據(jù)之前會發(fā)起TCP三次握手, 用以同步客戶端和服務端的序列號和確認號, 并交換TCP報文信息.
三次握手時序圖如下:
TCP三次握手過程如下:
- 客戶端發(fā)送一個SVN=1, Seq=X的數(shù)據(jù)包到服務器端口(第一次握手, 由瀏覽器發(fā)起, 告訴服務器我要發(fā)送請求了)
- 服務器返回一個帶有SVN=1, ACK=X+1, Seq=Y的響應包來傳達確認信息(第二次握手, 由服務器發(fā)起, 告訴瀏覽器我準備接受了, 你可以發(fā)送請求了)
- 客戶端再回傳一個ACK=Y+1, Seq=Z的數(shù)據(jù)包, 代表"握手結束"(第三次握手, 由瀏覽器發(fā)送, 告訴服務器, 我收到服務器的請求了, 現(xiàn)在馬上發(fā)送請請給服務器)
為什么需要三次握手?
謝希仁著《計算機網(wǎng)絡》中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務端鹿蜀,因而產(chǎn)生錯誤”箕慧。
4. 發(fā)送HTTP請求
TCP三次握手結束后, 開始發(fā)送HTTP請求報文
請求報文由請求行(request line), 請求頭(request header), 請求體(request body)三大部分組成, 如下圖所示:
請求行(Request Line)
包含請求方法, URL, 協(xié)議版本
- 請求方法包含8徙: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE
- URL即請求地址, 由<協(xié)議>://<主機>:<端口>/<路徑>?<參數(shù)> 組成
- 協(xié)議版本即HTTP版本號
POST /demo/index.html HTTP/1.1
以上代碼中, "POST"代表請求方法, "/demo/index.html"表示URL, "HTTP/1.1"代表協(xié)議和協(xié)議版本, 現(xiàn)在比較流行的是HTTP 1.1版本.
請求頭(Request Header)
包含請求的附加信息, 由關鍵字/值對組成, 每行一對, 關鍵字生值由英文冒號":"分隔
請求頭部通知服務器有關于客戶端請求的信息, 它包含許多有關于客戶端環(huán)境和請求正文的有用信息. 其中, 比如:
- Host, 表示主機名, 虛擬主機
- Connection: HTTP/1.1增加的, 使用keep-alive, 即持久連接, 一個連接可以發(fā)多個請求
- User-Agent, 請求發(fā)出者, 兼容性以及定制化需求
請求體(Request Body)
可以承載多個請求參數(shù)的數(shù)據(jù), 包含回車符, 換行符和請求數(shù)據(jù), 并不是所有請求都有請求數(shù)據(jù).
name=tom&password=1234&realName=tomson
上面代碼, 承載著name, password, realName三個請求參數(shù).
5. 服務器處理請求并返回HTTP報文
服務器
服務器是網(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)生的結果作為響應绝葡。
MVC后臺處理
后臺開發(fā)現(xiàn)在有很多框架,但大部分都還是按照 MVC 設計模式進行搭建的腹鹉。
MVC 是一個設計模式藏畅,將應用程序分成三個核心部件:模型(model)-- 視圖(view)--控制器(controller),它們各自處理自己的任務功咒,實現(xiàn)輸入愉阎、處理和輸出的分離。
MVC架構
視圖(view), 它是提供給用戶的操作界面力奋,是程序的外殼榜旦。
模型(model), 模型主要負責數(shù)據(jù)交互。在 MVC 的三個部件中景殷,模型擁有最多的處理任務溅呢。一個模型能為多個視圖提供數(shù)據(jù)。
控制器(controller), 它負責根據(jù)用戶從"視圖層"輸入的指令猿挚,選取"模型層"中的數(shù)據(jù)咐旧,然后對其進行相應的操作,產(chǎn)生最終結果亭饵。控制器屬于管理者角色梁厉,從視圖接收請求并決定調用哪個模型構件去處理請求辜羊,然后再確定用哪個視圖來顯示模型處理返回的數(shù)據(jù)。
這三層是緊密聯(lián)系在一起的词顾,但又是互相獨立的八秃,每一層內部的變化不影響其他層。每一層都對外提供接口(Interface)肉盹,供上面一層調用昔驱。
在這個階段中, 瀏覽器發(fā)送請求, 先經(jīng)過控制器,控制器進行邏輯處理和請求分發(fā)上忍,接著會調用模型骤肛,這一階段模型會獲取 redis db 以及 MySQL(等數(shù)據(jù)庫) 的數(shù)據(jù)纳本,獲取數(shù)據(jù)后將渲染好的頁面,響應信息會以響應報文的形式返回給客戶端腋颠,最后瀏覽器通過渲染引擎將網(wǎng)頁呈現(xiàn)在用戶面前.
HTTP響應報文
響應報文由響應行(request line)繁成、響應頭部(header)、響應主體三個部分組成淑玫。
- 響應行, 包含協(xié)議版本, 狀態(tài)碼, 狀態(tài)碼描述
- 狀態(tài)碼規(guī)則
- 1xx, 指示信息, 表示請求已接收, 繼續(xù)處理
- 2xx, 成功, 表示請求已被成功接收和處理.
- 3xx, 重定向, 表示要完成請求必須進行更進一步操作
- 4xx, 客戶端錯誤, 表示有語法錯誤或請求無法實現(xiàn)
- 5xx, 服務器端錯誤, 表示服務器未能實現(xiàn)合法的請求
- 狀態(tài)碼規(guī)則
- 響應頭部包含響應報文的附加信息, 由 名/值 對組成
- 響應主體包含回車符, 換行符和響應返回數(shù)據(jù), 并不是所有響應報文都有響應數(shù)據(jù)
6. 瀏覽喊叫解析渲染頁面
瀏覽器拿到響應文本 HTML 后巾腕,接下來介紹下瀏覽器渲染機制
瀏覽器解析渲染頁面大致分為5個步驟:
- 根據(jù)HTML, 解析出DOM樹
- 根據(jù)CSS, 解析生成CSS規(guī)則樹
- 結合DOM樹和CSS規(guī)則樹, 生成渲染樹
- 根據(jù)渲染樹計算每一個節(jié)點的信息
- 根據(jù)計算好的信息繪制頁面
根據(jù)HTML解析DOM樹
- 根據(jù) HTML 的內容,將標簽按照結構解析成為 DOM 樹絮蒿,DOM 樹解析的過程是一個深度優(yōu)先遍歷尊搬。即先構建當前節(jié)點的所有子節(jié)點瓷蛙,再構建下一個兄弟節(jié)點泊脐。
- 在讀取 HTML 文檔,構建 DOM 樹的過程中娘纷,若遇到 script 標簽回铛,則 DOM 樹的構建會暫停狗准,直至腳本執(zhí)行完畢。
根據(jù)CSS, 解析生成CSS規(guī)則樹
- 解析 CSS 規(guī)則樹時 js 執(zhí)行將暫停茵肃,直至 CSS 規(guī)則樹就緒腔长。
- 瀏覽器在 CSS 規(guī)則樹生成之前不會進行渲染。
結合DOM樹和CSS規(guī)則樹, 生成渲染樹
- DOM 樹和 CSS 規(guī)則樹全部準備好了以后验残,瀏覽器才會開始構建渲染樹捞附。
- 精簡 CSS , 可以加快 CSS 規(guī)則樹的構建,從而加快頁面相應速度您没。
根據(jù)渲染樹計算每一個節(jié)點的信息(布局)
- 布局:通過渲染樹中渲染對象的信息鸟召,計算出每一個渲染對象的位置和尺寸
- 回流:在布局完成后,發(fā)現(xiàn)了某個部分發(fā)生了變化影響了布局氨鹏,那就需要倒回去重新渲染欧募。
根據(jù)計算好的信息繪制頁面
- 繪制階段,系統(tǒng)會遍歷呈現(xiàn)樹仆抵,并調用呈現(xiàn)器的“paint”方法跟继,將呈現(xiàn)器的內容顯示在屏幕上。
- 重繪:某個元素的背景顏色镣丑,文字顏色等舔糖,不影響元素周圍或內部布局的屬性,將只會引起瀏覽器的重繪莺匠。
- 回流:某個元素的尺寸發(fā)生了變化金吗,則需重新計算渲染樹,重新渲染。
7. 斷開連接
當數(shù)據(jù)傳送完畢, 需要斷開TCP連接, 此時發(fā)起TCP四次揮手
TCP四次揮手時序圖如下:
- 發(fā)起方向被動方發(fā)送報文摇庙,F(xiàn)in旱物、Ack、Seq跟匆,表示已經(jīng)沒有數(shù)據(jù)傳輸了异袄。并進入 FIN_WAIT_1 狀態(tài)。(第一次揮手:由瀏覽器發(fā)起的玛臂,發(fā)送給服務器烤蜕,我請求報文發(fā)送完了,你準備關閉吧)
- 被動方發(fā)送報文迹冤,Ack讽营、Seq,表示同意關閉請求泡徙。此時主機發(fā)起方進入 FIN_WAIT_2 狀態(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ā)起唾琼,告訴服務器兄春,我響應報文接受完了澎剥,我準備關閉了,你也準備吧)
本文部分內容摘至網(wǎng)絡