前言
打開瀏覽器從輸入網(wǎng)址到網(wǎng)頁呈現(xiàn)在大家面前沿彭,背后到底發(fā)生了什么?經(jīng)歷怎么樣的一個過程尖滚?先給大家來張總體流程圖,具體步驟請看下文分解瞧柔!
總體來說分為以下幾個過程:
- DNS 解析:將域名解析成 IP 地址
- TCP 連接:TCP 三次握手
- 發(fā)送 HTTP 請求
- 服務(wù)器處理請求并返回 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)服務(wù)的類型倒谷。常見的協(xié)議有 http、https糙箍、ftp渤愁、file,其中最常見的類型是 http深夯,而 https 則是進(jìn)行加密的網(wǎng)絡(luò)傳輸抖格。
host - 定義域主機(jī)(http 的默認(rèn)主機(jī)是 www)
domain - 定義因特網(wǎng)域名,比如 w3school.com.cn
port - 定義主機(jī)上的端口號(http 的默認(rèn)端口號是 80)
path - 定義服務(wù)器上的路徑(如果省略咕晋,則文檔必須位于網(wǎng)站的根目錄中)雹拄。
filename - 定義文檔/資源的名稱
二、域名解析(DNS)
在瀏覽器輸入網(wǎng)址后掌呜,首先要經(jīng)過域名解析滓玖,因?yàn)闉g覽器并不能直接通過域名找到對應(yīng)的服務(wù)器,而是要通過 IP 地址质蕉。大家這里或許會有個疑問----計(jì)算機(jī)既可以被賦予 IP 地址势篡,也可以被賦予主機(jī)名和域名翩肌。比如 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)絡(luò)和每一臺主機(jī)分配一個邏輯地址,以此來屏蔽物理地址的差異祝钢。IP 地址是一個 32 位的二進(jìn)制數(shù)比规,比如 127.0.0.1 為本機(jī) IP。
域名就相當(dāng)于 IP 地址喬裝打扮的偽裝者拦英,帶著一副面具蜒什。它的作用就是便于記憶和溝通的一組服務(wù)器的地址。用戶通常使用主機(jī)名或域名來訪問對方的計(jì)算機(jī)疤估,而不是直接通過 IP 地址訪問灾常。因?yàn)榕c IP 地址的一組純數(shù)字相比,用字母配合數(shù)字的表示形式來指定計(jì)算機(jī)名更符合人類的記憶習(xí)慣铃拇。但要讓計(jì)算機(jī)去理解名稱钞瀑,相對而言就變得困難了。因?yàn)橛?jì)算機(jī)更擅長處理一長串?dāng)?shù)字慷荔。為了解決上述的問題雕什,DNS 服務(wù)應(yīng)運(yùn)而生。
2.什么是域名解析
DNS 協(xié)議提供通過域名查找 IP 地址显晶,或逆向從 IP 地址反查域名的服務(wù)贷岸。DNS 是一個網(wǎng)絡(luò)服務(wù)器,我們的域名解析簡單來說就是在 DNS 上記錄一條信息記錄磷雇。
例如 baidu.com 220.114.23.56(服務(wù)器外網(wǎng)IP地址)80(服務(wù)器端口號)
3. 瀏覽器如何通過域名去查詢 URL 對應(yīng)的 IP 呢
- 瀏覽器緩存:瀏覽器會按照一定的頻率緩存 DNS 記錄偿警。
- 操作系統(tǒng)緩存:如果瀏覽器緩存中找不到需要的 DNS 記錄,那就去操作系統(tǒng)中找倦春。
- 路由緩存:路由器也有 DNS 緩存户敬。
- ISP 的 DNS 服務(wù)器:ISP 是互聯(lián)網(wǎng)服務(wù)提供商(Internet Service Provider)的簡稱,ISP 有專門的 DNS 服務(wù)器應(yīng)對 DNS 查詢請求睁本。
- 根服務(wù)器:ISP 的 DNS 服務(wù)器還找不到的話尿庐,它就會向根服務(wù)器發(fā)出請求,進(jìn)行遞歸查詢(DNS 服務(wù)器先問根域名服務(wù)器.com 域名服務(wù)器的 IP 地址呢堰,然后再問.baidu 域名服務(wù)器抄瑟,依次類推)
4. 小結(jié)
瀏覽器通過向 DNS 服務(wù)器發(fā)送域名,DNS 服務(wù)器查詢到與域名相對應(yīng)的 IP 地址,然后返回給瀏覽器皮假,瀏覽器再將 IP 地址打在協(xié)議上鞋拟,同時請求參數(shù)也會在協(xié)議搭載,然后一并發(fā)送給對應(yīng)的服務(wù)器惹资。接下來介紹向服務(wù)器發(fā)送 HTTP 請求階段贺纲,HTTP 請求分為三個部分:TCP 三次握手、http 請求響應(yīng)信息褪测、關(guān)閉 TCP 連接猴誊。
三教届、TCP 三次握手
在客戶端發(fā)送數(shù)據(jù)之前會發(fā)起 TCP 三次握手用以同步客戶端和服務(wù)端的序列號和確認(rèn)號郁轻,并交換 TCP 窗口大小信息居暖。
1.TCP 三次握手的過程如下:
客戶端發(fā)送一個帶 SYN=1贩耐,Seq=X 的數(shù)據(jù)包到服務(wù)器端口(第一次握手,由瀏覽器發(fā)起罚攀,告訴服務(wù)器我要發(fā)送請求了)
服務(wù)器發(fā)回一個帶 SYN=1鲜棠, ACK=X+1亭敢, Seq=Y 的響應(yīng)包以示傳達(dá)確認(rèn)信息(第二次握手畏吓,由服務(wù)器發(fā)起墨状,告訴瀏覽器我準(zhǔn)備接受了,你趕緊發(fā)送吧)
客戶端再回傳一個帶 ACK=Y+1菲饼, Seq=Z 的數(shù)據(jù)包歉胶,代表“握手結(jié)束”(第三次握手,由瀏覽器發(fā)送巴粪,告訴服務(wù)器,我馬上就發(fā)了粥谬,準(zhǔn)備接受吧)
2.為啥需要三次握手
謝希仁著《計(jì)算機(jī)網(wǎng)絡(luò)》中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務(wù)端肛根,因而產(chǎn)生錯誤”。
四漏策、發(fā)送 HTTP 請求
TCP 三次握手結(jié)束后派哲,開始發(fā)送 HTTP 請求報文。
請求報文由請求行(request line)掺喻、請求頭(header)芭届、請求體四個部分組成,如下圖所示:
1.請求行包含請求方法、URL感耙、協(xié)議版本
- 請求方法包含 8 種:GET褂乍、POST、PUT即硼、DELETE逃片、PATCH、HEAD只酥、OPTIONS褥实、TRACE呀狼。
- URL 即請求地址,由 <協(xié)議>://<主機(jī)>:<端口>/<路徑>?<參數(shù)> 組成
- 協(xié)議版本即 http 版本號
POST /chapter17/user.html HTTP/1.1
以上代碼中“POST”代表請求方法损离,“/chapter17/user.html”表示 URL哥艇,“HTTP/1.1”代表協(xié)議和協(xié)議的版本。現(xiàn)在比較流行的是 Http1.1 版本
2.請求頭包含請求的附加信息僻澎,由關(guān)鍵字/值對組成貌踏,每行一對,關(guān)鍵字和值用英文冒號“:”分隔怎棱。
請求頭部通知服務(wù)器有關(guān)于客戶端請求的信息哩俭。它包含許多有關(guān)的客戶端環(huán)境和請求正文的有用信息。其中比如:Host拳恋,表示主機(jī)名凡资,虛擬主機(jī);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ù)芒划。
五冬竟、服務(wù)器處理請求并返回 HTTP 報文
1. 服務(wù)器
服務(wù)器是網(wǎng)絡(luò)環(huán)境中的高性能計(jì)算機(jī),它偵聽網(wǎng)絡(luò)上的其他計(jì)算機(jī)(客戶機(jī))提交的服務(wù)請求民逼,并提供相應(yīng)的服務(wù)泵殴,比如網(wǎng)頁服務(wù)、文件下載服務(wù)缴挖、郵件服務(wù)袋狞、視頻服務(wù)。而客戶端主要的功能是瀏覽網(wǎng)頁、看視頻苟鸯、聽音樂等等同蜻,兩者截然不同。 每臺服務(wù)器上都會安裝處理請求的應(yīng)用——web server早处。常見的 web server 產(chǎn)品有 apache湾蔓、nginx、IIS 或 Lighttpd 等砌梆。
web server 擔(dān)任管控的角色默责,對于不同用戶發(fā)送的請求,會結(jié)合配置文件咸包,把不同請求委托給服務(wù)器上處理相應(yīng)請求的程序進(jìn)行處理(例如 CGI 腳本桃序,JSP 腳本,servlets烂瘫,ASP 腳本媒熊,服務(wù)器端 JavaScript,或者一些其它的服務(wù)器端技術(shù)等)坟比,然后返回后臺程序處理產(chǎn)生的結(jié)果作為響應(yīng)芦鳍。
2.MVC 后臺處理階段
后臺開發(fā)現(xiàn)在有很多框架,但大部分都還是按照 MVC 設(shè)計(jì)模式進(jìn)行搭建的葛账。
MVC 是一個設(shè)計(jì)模式柠衅,將應(yīng)用程序分成三個核心部件:模型(model)-- 視圖(view)--控制器(controller),它們各自處理自己的任務(wù)籍琳,實(shí)現(xiàn)輸入菲宴、處理和輸出的分離。
1趋急、視圖(view)
它是提供給用戶的操作界面裙顽,是程序的外殼。
2宣谈、模型(model)
模型主要負(fù)責(zé)數(shù)據(jù)交互。在 MVC 的三個部件中键科,模型擁有最多的處理任務(wù)闻丑。一個模型能為多個視圖提供數(shù)據(jù)。
3勋颖、控制器(controller)
它負(fù)責(zé)根據(jù)用戶從"視圖層"輸入的指令嗦嗡,選取"模型層"中的數(shù)據(jù),然后對其進(jìn)行相應(yīng)的操作饭玲,產(chǎn)生最終結(jié)果侥祭。控制器屬于管理者角色,從視圖接收請求并決定調(diào)用哪個模型構(gòu)件去處理請求,然后再確定用哪個視圖來顯示模型處理返回的數(shù)據(jù)矮冬。
這三層是緊密聯(lián)系在一起的谈宛,但又是互相獨(dú)立的,每一層內(nèi)部的變化不影響其他層胎署。每一層都對外提供接口(Interface)吆录,供上面一層調(diào)用。
至于這一階段發(fā)生什么琼牧?簡而言之恢筝,首先瀏覽器發(fā)送過來的請求先經(jīng)過控制器,控制器進(jìn)行邏輯處理和請求分發(fā)巨坊,接著會調(diào)用模型撬槽,這一階段模型會獲取 redis db 以及 MySQL 的數(shù)據(jù),獲取數(shù)據(jù)后將渲染好的頁面趾撵,響應(yīng)信息會以響應(yīng)報文的形式返回給客戶端侄柔,最后瀏覽器通過渲染引擎將網(wǎng)頁呈現(xiàn)在用戶面前。
3.http 響應(yīng)報文
響應(yīng)報文由響應(yīng)行(request line)鼓寺、響應(yīng)頭部(header)勋拟、響應(yīng)主體三個部分組成。如下圖所示:
(1) 響應(yīng)行包含:協(xié)議版本妈候,狀態(tài)碼敢靡,狀態(tài)碼描述
狀態(tài)碼規(guī)則如下:
1xx:指示信息--表示請求已接收,繼續(xù)處理苦银。
2xx:成功--表示請求已被成功接收啸胧、理解、接受幔虏。
3xx:重定向--要完成請求必須進(jìn)行更進(jìn)一步的操作纺念。
4xx:客戶端錯誤--請求有語法錯誤或請求無法實(shí)現(xiàn)。
5xx:服務(wù)器端錯誤--服務(wù)器未能實(shí)現(xiàn)合法的請求想括。
(2) 響應(yīng)頭部包含響應(yīng)報文的附加信息陷谱,由 名/值 對組成
(3) 響應(yīng)主體包含回車符、換行符和響應(yīng)返回?cái)?shù)據(jù)瑟蜈,并不是所有響應(yīng)報文都有響應(yīng)數(shù)據(jù)
六烟逊、瀏覽器解析渲染頁面
瀏覽器拿到響應(yīng)文本 HTML 后,接下來介紹下瀏覽器渲染機(jī)制
瀏覽器解析渲染頁面分為一下五個步驟:
- 根據(jù) HTML 解析出 DOM 樹
- 根據(jù) CSS 解析生成 CSS 規(guī)則樹
- 結(jié)合 DOM 樹和 CSS 規(guī)則樹铺根,生成渲染樹
- 根據(jù)渲染樹計(jì)算每一個節(jié)點(diǎn)的信息
- 根據(jù)計(jì)算好的信息繪制頁面
1.根據(jù) HTML 解析 DOM 樹
- 根據(jù) HTML 的內(nèi)容宪躯,將標(biāo)簽按照結(jié)構(gòu)解析成為 DOM 樹,DOM 樹解析的過程是一個深度優(yōu)先遍歷位迂。即先構(gòu)建當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn)访雪,再構(gòu)建下一個兄弟節(jié)點(diǎn)详瑞。
- 在讀取 HTML 文檔,構(gòu)建 DOM 樹的過程中臣缀,若遇到 script 標(biāo)簽坝橡,則 DOM 樹的構(gòu)建會暫停,直至腳本執(zhí)行完畢肝陪。
2.根據(jù) CSS 解析生成 CSS 規(guī)則樹
- 解析 CSS 規(guī)則樹時 js 執(zhí)行將暫停驳庭,直至 CSS 規(guī)則樹就緒。
- 瀏覽器在 CSS 規(guī)則樹生成之前不會進(jìn)行渲染氯窍。
3.結(jié)合 DOM 樹和 CSS 規(guī)則樹饲常,生成渲染樹
- DOM 樹和 CSS 規(guī)則樹全部準(zhǔn)備好了以后,瀏覽器才會開始構(gòu)建渲染樹狼讨。
- 精簡 CSS 并可以加快 CSS 規(guī)則樹的構(gòu)建贝淤,從而加快頁面相應(yīng)速度。
4.根據(jù)渲染樹計(jì)算每一個節(jié)點(diǎn)的信息(布局)
- 布局:通過渲染樹中渲染對象的信息政供,計(jì)算出每一個渲染對象的位置和尺寸
- 回流:在布局完成后播聪,發(fā)現(xiàn)了某個部分發(fā)生了變化影響了布局,那就需要倒回去重新渲染布隔。
5.根據(jù)計(jì)算好的信息繪制頁面
- 繪制階段离陶,系統(tǒng)會遍歷呈現(xiàn)樹,并調(diào)用呈現(xiàn)器的“paint”方法衅檀,將呈現(xiàn)器的內(nèi)容顯示在屏幕上招刨。
- 重繪:某個元素的背景顏色,文字顏色等哀军,不影響元素周圍或內(nèi)部布局的屬性沉眶,將只會引起瀏覽器的重繪。
- 回流:某個元素的尺寸發(fā)生了變化杉适,則需重新計(jì)算渲染樹谎倔,重新渲染。
七猿推、斷開連接
當(dāng)數(shù)據(jù)傳送完畢片习,需要斷開 tcp 連接,此時發(fā)起 tcp 四次揮手蹬叭。
- 發(fā)起方向被動方發(fā)送報文毯侦,F(xiàn)in、Ack具垫、Seq,表示已經(jīng)沒有數(shù)據(jù)傳輸了试幽。并進(jìn)入 FIN_WAIT_1 狀態(tài)筝蚕。(第一次揮手:由瀏覽器發(fā)起的卦碾,發(fā)送給服務(wù)器,我請求報文發(fā)送完了起宽,你準(zhǔn)備關(guān)閉吧)
- 被動方發(fā)送報文洲胖,Ack、Seq坯沪,表示同意關(guān)閉請求绿映。此時主機(jī)發(fā)起方進(jìn)入 FIN_WAIT_2 狀態(tài)。(第二次揮手:由服務(wù)器發(fā)起的腐晾,告訴瀏覽器叉弦,我請求報文接受完了,我準(zhǔn)備關(guān)閉了藻糖,你也準(zhǔn)備吧)
- 被動方向發(fā)起方發(fā)送報文段淹冰,F(xiàn)in、Ack巨柒、Seq樱拴,請求關(guān)閉連接。并進(jìn)入 LAST_ACK 狀態(tài)洋满。(第三次揮手:由服務(wù)器發(fā)起晶乔,告訴瀏覽器,我響應(yīng)報文發(fā)送完了牺勾,你準(zhǔn)備關(guān)閉吧)
- 發(fā)起方向被動方發(fā)送報文段正罢,Ack、Seq禽最。然后進(jìn)入等待 TIME_WAIT 狀態(tài)腺怯。被動方收到發(fā)起方的報文段以后關(guān)閉連接。發(fā)起方等待一定時間未收到回復(fù)川无,則正常關(guān)閉呛占。(第四次揮手:由瀏覽器發(fā)起,告訴服務(wù)器懦趋,我響應(yīng)報文接受完了晾虑,我準(zhǔn)備關(guān)閉了,你也準(zhǔn)備吧)
給大家推薦一個好用的BUG監(jiān)控工具Fundebug仅叫,歡迎免費(fèi)試用帜篇!