文章目錄
前言
- 瀏覽器中輸入URL返回頁面全過程
- DNS域名解析過程
- TCP的三次握手、四次揮手
一、瀏覽器中輸入域名
二、解析域名
-
2.1 具體過程
-
2.2 知識補充
- 2.2.1 域名體系結構
- 2.2.2 查詢方式——遞迴查詢、迭代查詢
- 2.2.3 DNS域名解析過程
三、瀏覽器與目標伺服器建立TCP連線
-
3.1 詳解
-
3.2 知識補充
- 3.2.1 TCP 與 UDP
- 3.2.2 TCP的三次握手
- 3.2.3 TCP的四次揮手
四、瀏覽器傳送HTTP請求
五、伺服器響應HTTP請求
六、TCP釋放連線(TCP四次揮手)
七、瀏覽器解析響應內容,處理和渲染
八、總結
前言
瀏覽器中輸入URL返回頁面全過程
在軟體開發、Java、後端的面試中,瀏覽器中輸入URL到頁面返回的全過程 是一道非常經典的面試題,更是經常被作為面試的壓軸題出現。有時也會透過其他方式來問,譬如:
- 前端發起請求之後到達後端,中間過程是什麼
- 當你輸入一個網址時,實際會發生什麼
本質上為同一個問題,具體分為7個步驟:
- 瀏覽器中輸入域名
- 解析域名,找到主機ip
- 瀏覽器與目標伺服器建立TCP連線。瀏覽器利用IP直接與網站主機通訊,三次握手、建立TCP連線。瀏覽器會以一個隨機埠向服務端的web程式80埠發起TCP連線
- 瀏覽器透過http協議向目標伺服器傳送請求。建立TCP連線後,瀏覽器向主機發起一個HTTP請求
- 伺服器響應請求,將對應資料返回給瀏覽器
- TCP釋放連結
- 瀏覽器解析響應內容,進行渲染,呈現給使用者
DNS域名解析過程
假定某客戶機想獲知域名為xxx.example.com主機的IP地址,域名解析的過程(共使用8個UDP報文)如下:
- 客戶機向其本地域名伺服器發出DNS請求報文
- 本地域名伺服器收到請求後,查詢本地快取,若沒有該記錄,則以DNS客戶的身份向根域名伺服器發出解析請求
- 根域名伺服器收到請求後,判斷該域名屬於.com域,將對應的頂級域名伺服器dns.com的IP地址返回給本地域名伺服器
- 本地域名伺服器向頂級域名伺服器dns.com發出解析請求報文
- 頂級域名伺服器dns.com收到請求後,判斷該域名屬於example.com域,因此將對應的授權域名伺服器dns.example.com的IP地址返回給本地域名伺服器
- 本地域名伺服器向授權域名伺服器dns.example.com發起解析請求報文
- 授權域名伺服器dns.example.com收到請求後,將查詢結果返回給本地域名伺服器
- 本地域名伺服器將查詢結果儲存到本地快取,同時返回給客戶機
- 瀏覽器檢查快取,如果沒有找到需要的IP地址,會向本地DNS伺服器請求(遞迴查詢)
- 本地DNS伺服器如果沒有對應的IP地址,會向根DNS伺服器查詢,進而迭代向頂級域名伺服器、許可權域名伺服器查詢,直到獲取到目標伺服器的IP地址,並返回給瀏覽器(迭代查詢)
TCP的三次握手、四次揮手
見本文3.2.2、3.2.3小節。
一、瀏覽器中輸入域名
瀏覽器中輸入域名 www.baidu.com,客戶端發起請求。
二、解析域名
2.1 具體過程
瀏覽器會把輸入的域名解析成對應的IP,過程如下:
- 查詢快取:瀏覽器會先查詢當前URL的快取記錄(瀏覽器快取、系統快取、路由快取),看是否有域名對應的IP地址。如存在快取,就直接顯示;如果沒有,接著下一步
- 瀏覽器快取:簡單來說,瀏覽器快取就是把一個已經請求過的Web資源(如html頁面,圖片,js,資料等)複製一份副本儲存在瀏覽器中。
- 作業系統快取:瀏覽器快取中沒有記錄,再到本地作業系統快取中查詢,一般在本機hosts檔案(如有直接獲取)
- 路由快取:路由器也有DNS快取(如有直接獲取)
- 接著是對本地DNS伺服器進行遞迴查詢,看是否有域名對應的IP。主機向本地域名伺服器的查詢一般都是採用遞迴查詢。所謂遞迴查詢就是如果主機所詢問的本地域名伺服器不知道被查詢域名的IP地址,那麼本地域名伺服器就以DNS客戶的身份,向其他根域名伺服器繼續發出查詢請求報文,而不是讓該主機自己進行下一步查詢。(本地域名伺服器地址是透過DHPC協議獲取地址,DHPC是負責分配IP地址的)
- 本地域名伺服器採用迭代查詢,它先向一個根域名伺服器查詢。本地域名伺服器向根域名伺服器的查詢一般都是採用迭代查詢。所謂迭代查詢就是當根域名伺服器收到本地域名伺服器發出的查詢請求報文後,要麼告訴本地域名伺服器下一步應該查詢哪一個域名伺服器,然後本地伺服器自己進行後續的查詢。(而不是替代本地伺服器進行後續查詢)
- 根域名伺服器告訴本地域名伺服器,下一次應查詢的頂級域名伺服器dns.com的IP地址(有關各域名伺服器的關係 可見下面2.2.1小節)
- 本地域名伺服器向頂級域名伺服器dns.com進行查詢
- 頂級域名伺服器dns.com告訴本地域名伺服器,下一次應查詢的許可權域名伺服器dns.baidu.com的IP地址
- 本地域名伺服器向許可權域名伺服器dns.baidu.com進行查詢
- 許可權域名伺服器dns.baidu.com告訴本地域名伺服器,所查詢的主機www.baidu.com的IP地址。
本地域名伺服器最後把查詢結果告訴主機。
2.2 知識補充
2.2.1 域名體系結構
DNS服務協議採用類似目錄樹的層次結構記錄域名與IP地址的對映對應關係,形成一個分散式的資料庫系統:DNS 結構模型
域名空間的樹狀圖:
域名組成圖:
由高向低進行層次劃分,可分為以下幾大類:
分類 | 作用 |
---|---|
根域名伺服器 | 最高層次的域名伺服器,本地域名伺服器解析不了的域名就會向其求助 |
頂級域名伺服器 | 負責管理在該頂級域名伺服器下注冊的二級域名 |
許可權域名伺服器 | 負責一個區的域名解析工作 |
本地域名伺服器 | 當一個主機發出DNS查詢請求時,這個查詢請求首先發給本地域名伺服器 |
2.2.2 查詢方式——遞迴查詢、迭代查詢
1、遞迴查詢
遞迴查詢是一種DNS伺服器的查詢模式,在該模式下DNS伺服器接收到客戶機請求,必須使用一個準確的查詢結果回覆客戶機。如果DNS伺服器本地沒有儲存查詢DNS資訊,那麼該伺服器會詢問其他伺服器,並將返回的查詢結果提交給客戶機
總的來說:就是客戶機傳送請求後自己只用等待結果即可,中間具體過程交給伺服器實現
例子:當你在瀏覽器中輸入一個網址時,你的計算機的DNS客戶端會向本地DNS伺服器傳送一個遞迴查詢請求,以獲取該域名對應的IP地址
2、迭代查詢
DNS伺服器另外一種查詢方式為迭代查詢,當客戶機傳送查詢請求時,DNS伺服器並不直接回複查詢結果,而是告訴客戶機另一臺DNS伺服器地址,客戶機再向這臺DNS伺服器提交請求,依次迴圈直到返回查詢的結果為止
總的來說:客戶機的請求需要自己挨個去查詢才能得到結果,伺服器沒有結果時只會給你提供其它伺服器的地址,而不會幫你去請求查詢,這與遞迴查詢截然相反
3、總結
從遞迴和迭代查詢可以看出:
- 客戶端-本地DNS伺服器:這部分屬於遞迴查詢
- 本地DNS服務端----外網:這部分屬於迭代查詢
遞迴查詢時,返回的結果只有兩種:查詢成功或查詢失敗
迭代查詢又稱作重指引,返回的是最佳的查詢點或者主機地址
2.2.3 DNS域名解析過程
假定某客戶機想獲知域名為xxx.example.com主機的IP地址,域名解析的過程(共使用8個UDP報文)如下:
- 客戶機向其本地域名伺服器發出DNS請求報文
- 本地域名伺服器收到請求後,查詢本地快取,若沒有該記錄,則以DNS客戶的身份向根域名伺服器發出解析請求
- 根域名伺服器收到請求後,判斷該域名屬於.com域,將對應的頂級域名伺服器dns.com的IP地址返回給本地域名伺服器
- 本地域名伺服器向頂級域名伺服器dns.com發出解析請求報文
- 頂級域名伺服器dns.com收到請求後,判斷該域名屬於example.com域,因此將對應的授權域名伺服器dns.example.com的IP地址返回給本地域名伺服器
- 本地域名伺服器向授權域名伺服器dns.example.com發起解析請求報文
- 授權域名伺服器dns.example.com收到請求後,將查詢結果返回給本地域名伺服器
- 本地域名伺服器將查詢結果儲存到本地快取,同時返回給客戶機
- 瀏覽器檢查快取,如果沒有找到需要的IP地址,會向本地DNS伺服器請求(遞迴查詢)
- 本地DNS伺服器如果沒有對應的IP地址,會向根DNS伺服器查詢,進而迭代向頂級域名伺服器、許可權域名伺服器查詢,直到獲取到目標伺服器的IP地址,並返回給瀏覽器(迭代查詢)
三、瀏覽器與目標伺服器建立TCP連線
3.1 詳解
- 主機瀏覽器透過DNS解析得到了目標伺服器的IP地址後,與伺服器建立TCP連線(瀏覽器會以一個隨機埠向服務端的web程式80埠發起TCP連線)
- TCP三次握手建立連線:瀏覽器所在的客戶機向伺服器發出連線請求報文;伺服器接收報文後,同意建立連線,向客戶機發出確認報文;客戶機接收到確認報文後,再次向伺服器發出報文,確認已接收到確認報文;此處客戶機與伺服器之間的TCP連線建立完成,開始通訊。
3.2 知識補充
3.2.1 TCP 與 UDP
什麼是TCP? TCP是傳輸控制協議,是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議。
- TCP:用於對傳輸準確性要求特別高的場景。如檔案傳輸、傳送和接收郵件、遠端登入等
- UDP:一般用於即時通訊。如語音、影片、直播等
TCP、UDP的區別(重要)
TCP | UDP |
---|---|
面向連線 | 無連線 |
提供可靠服務 | 不保證可靠互動 |
有狀態 | 無狀態 |
面向位元組流 | 面向報文 |
傳輸效率較慢 | 傳輸效率較快 |
有擁塞控制 | 沒有擁塞控制 |
每一條TCP連線只能是 |
支援一對一、一對多、多對一、多對多 |
首部開銷20位元組 | 首部開銷8位元組 |
執行於TCP、UDP上的協議
- 執行於TCP之上的協議:HTTP、HTTPS、FTP、SMTP、POP3/IMAP、Telnet、SSH
- 執行於UDP之上的協議
- DHCP:動態主機配置協議,動態配置IP地址
- DNS:域名系統(DNS,Domain Name System)將人類可讀的域名(如www.baidu.com)轉化為機器可讀的IP地址(如220.181.38.148),可將其理解為專為網際網路設計的電話簿。實際上DNS同時支援UDP、TCP
3.2.2 TCP的三次握手
假設傳送端為客戶端,接收端為服務端。開始客戶端、服務端的狀態都是CLOSED
- 第一次握手(無任何狀態):客戶端向服務端發起建立連線請求,客戶端會隨機生成一個起始序列號x,客戶端向服務端傳送的欄位包含標誌位SYN=1,序列號seq=x。第一次握手後客戶端的狀態為SYN-SENT。此時服務端的狀態為LISTEN
- 第二次握手(保證:客戶端的傳送能力、伺服器的接收能力沒問題):服務端在收到客戶端發來的報文後,會隨機生成一個服務端的起始序列號y,然後給客戶端回覆一段報文,標誌位SYN=1,序列號seq=y,ACK=1,確認號ack=x+1。第二次握手後服務端的狀態為SYN-RCVD(SYN=1表示要和客戶端建立一個連線,ACK=1表示確認序號有效)
- 第三次握手(保證:客戶端的接收能力、伺服器的傳送能力沒問題):客戶端收到服務端發來的報文後,會再向服務端傳送報文。ACK=1,序列號seq=x+1,確認號ack=y+1。客戶、服務端狀態變為ESTABLISTED。此時連線建立完成
A<-->B
-
第一個包,即A發給B的SYN中途被丟,沒有到達B
- A會週期性超時重傳,直到收到B的確認
-
第二個包,即B發給A的SYN+ACK中途被丟,沒有到達A
- B會週期性超時重傳,直到收到A的確認
-
第三個包,即A發給B的ACK中途被丟,沒有到達B ——A發完ACK,單方面認為TCP為Established狀態,而B顯然認為TCP為Active狀態
- a.假定此時雙方都沒有資料傳送,B會週期性超時重傳,直到收到A的確認
- b.假定此時收到A的資料傳送,B收到A的Data+ACK,自然切換到established狀態,並接受A的Data
- c.假定B有資料傳送,資料傳送不了,會一直週期性超時重傳SYN+ACK,直到收到A的確認才可以傳送資料
3.2.3 TCP的四次揮手
-
A的應用程序先向B發出連線釋放報文段(FIN=1,Seq=u),並停止再傳送資料,主動關閉TCP連線,進入FIN-WAIT-1狀態。
-
B收到連線釋放報文段後傳送確認報文段(ACK=1,ack=u+1,seq=v),B進入CLOSE-WAIT狀態,此時的TCP處於半關閉狀態
-
A收到B的確認後,進入FIN-WAIT-2狀態,等待B發出的連線釋放報文段
-
B傳送完資料,就發出連線釋放報文段(FIN=1,seq=W,ACK=1,ack=u+1),B進入LAST-ACK狀態
-
A收到B的連線釋放報文段後,發出確認報文段(ACK=1,seq=u+1,ack=w+1),A進入TIME-WAIT狀態。此時TCP未釋放掉,需要經過時間等待計時器設定的2MSL(最大報文段生存時間)後,A進入C1OSE狀態。B在收到A發出的確認報文段後關閉連線,若沒收到則B會重傳連線釋放報文段
常見問題:
1)四次揮手為什麼要等待2MSL?
保證A傳送的最後一個ACK報文段能夠達到B。這個ACK報文段可能丟失,B收不到這個確認報文,就會超時重傳連線釋放報文段,A可以在這個2MSL時間內收到這個重傳的連線釋放報文段,接著A重傳一次確認,並重新啟動2MSL計時器,最後A和B都進入CLOSED狀態。若A在TIME-WAIT狀態不等待一段時間,而是傳送完ACK報文段立即進入CLOSED,則無法收到B重傳的連線釋放報文段,那麼A不會再發一次確認報文段,B就無法正常進入CLOSED狀態
2)為什麼是四次揮手?
TCP是全雙工通訊,可以雙向傳輸資料。任何一方都可以在資料傳送結束後 發出連線釋放的通知,待對方確認後進入半關閉狀態。當另一方也沒有資料再傳送的時候,則發出連線釋放通知,對方確認後就完全關閉了TCP連線。
舉個例子,A和B打電話
- 第一次揮手:A說“我沒啥要說的了”
- 第二次揮手:B回答“我知道了”,但是B可能還會有要說的話,A不能要求B跟著自己的節奏結束通話
- 第三次揮手:於是B可能又巴拉巴拉說了一通,最後B說“我說完了”
- 第四次揮手:A回答“知道了”,這樣通話才算結束
隨機生成序列號的原因
- 提供安全性:防止TCP序列號預測攻擊和會話劫持
- 避免舊連線干擾:確保新舊連線的隔離,防止舊資料包乾擾新連線
- 增強網路可靠性:減少網路延遲和重新傳輸造成的混淆
四、瀏覽器傳送HTTP請求
瀏覽器透過已建立的TCP連線,傳送HTTP請求,請求報文包括三部分,請求行、請求頭、請求體
-
請求行。例 POST /demo/index.html HTTP/1.1
- 請求方法。如get、post、put、delete、patch、head、options、trace
- URL
- 協議版本
-
請求頭。請求頭包含了請求的附加資訊,一般以key:value的形式存在。比如關於客戶端的資訊,host(主機名)
-
請求體。請求體包含了多個請求引數的資料,包含了回車符、換行符、請求資料(不是所有的請求都帶有請求資料)
瀏覽器向主機發起一個HTTP-GET方法報文請求。請求中包含訪問的URL,也就是http://www.baidu.com/ ,KeepAlive,長連線,還有User-Agent使用者瀏覽器作業系統資訊,編碼等。值得一提的是Accep-Encoding和Cookies項。Accept-Encoding一般採用gzip,壓縮之後傳輸html檔案。Cookies如果是首次訪問,會提示伺服器建立使用者快取資訊,如果不是,可以利用Cookies對應鍵值,找到相應快取,快取裡面存放著使用者名稱,密碼和一些使用者設定項。
五、伺服器響應HTTP請求
伺服器收到請求後處理請求,並返回響應報文資料。
-
後端伺服器接收到請求包,Web伺服器(如Nginx、Apache等)處理基礎的請求任務,如負載均衡、靜態資源提供等
-
應用伺服器處理請求
- Web伺服器將請求轉發給應用伺服器(如Tomcat、Node.js等)
- 中介軟體(如Spring、Express等)處理路由和中介軟體函式,如驗證、日誌記錄等
-
業務邏輯處理
- 應用伺服器依據請求路徑和引數,將請求分發到對應的業務處理邏輯中
- 可能會進行資料庫查詢、呼叫其他API服務、業務邏輯運算等操作。
- 資料庫及外部系統互動:如果需要資料庫查詢,應用伺服器會構造SQL語句或者請求ORM(物件關係對映)框架,資料庫接收請求並返回結果;可能還會呼叫其他微服務或第三方API,並處理響應結果
-
構建響應
- 應用伺服器完成業務處理後,構建HTTP響應,包括狀態碼、響應頭和響應體
- 響應體可能是HTML頁面、JSON資料、XML資料等。
-
傳送響應:應用伺服器將HTTP響應透過TCP連線傳送回客戶端。響應報文包含三部分
-
響應行:包含協議版本,狀態碼,狀態碼描述
-
響應頭:包含一些附加的響應資訊
-
響應主題:包含回車符、換行符和響應返回的資料(不是所有的響應都有響應資料)
-
補充:
1)如果報頭中Content-type為“text/html”,瀏覽器以HTML形式呈現,而不是下載檔案
2)對於大型網站存在多個主機站點,往往不會直接返回請求頁面,而是重定向。返回的狀態碼就不是200OK,而是301,302以3開頭的重定向碼,瀏覽器在獲取了重定向響應後,在響應報文中Location項找到重定向地址,瀏覽器重新第一步訪問即可
3)重定向是為了負載均衡或者匯入流量,提高SEO排名。利用一個前端伺服器接受請求,然後負載到不同的主機上,可以大大提高站點的業務併發處理能力;重定向也可將多個域名的訪問,集中到一個站點;由於baidu.com,www.baidu.com會被搜尋引擎認為是兩個網站,照成每個的連結數都會減少從而降低排名,永久重定向會將兩個地址關聯起來,搜尋引擎會認為是同一個網站,從而提高排名
六、TCP釋放連線(TCP四次揮手)
瀏覽器接收HTTP響應後,根據實際情況選擇關閉TCP連線或者保留重⽤,關閉TCP連線的四次握⼿如下:
- 瀏覽器向伺服器傳送報文(Fin=1,Ack=z,Seq=x),表示客戶端請求報文已經傳送完了,準備關閉了。並進入到FIN_WAIT_1狀態。,即斷開連線的請求(太陽下山了,我該回家乾飯了)到伺服器
- 伺服器收到客戶端的斷開請求後,傳送確認報文(Ack=x+1,Seq=z),表示統一關閉。此時主機進入FIN_WAIT_2狀態。,即伺服器接到請求後傳送確認收到請求的訊號(哦,我知道了)
- 伺服器在傳送完資料以後,也會向客戶端傳送斷開連線的報文(Fin=1,Ack=x,Seq=y),表示我沒有響應資料要傳了,準備關閉了。此時進入到LAST_ACK狀態,即伺服器向瀏覽器傳送斷開通知(你走吧,我也該回家抱娃了)
- 客戶端收到伺服器的關閉請求後,會傳送一個確認報文(Ack=y+1,Seq=x),表示同意關閉。伺服器收到客戶單的確認報文後關閉連線。而瀏覽器在等待一段時間後未收到回覆,則正常關閉。,即客戶端接到斷開通知後斷開連線並反饋一個確認訊號(嗯,走咯),伺服器收到確認訊號後也斷開連線;
Tips:為什麼不能三次揮手?有可能資料還未傳輸完成,所以伺服器要先確認後再發起斷開訊息
簡而言之:
- 瀏覽器所在主機向伺服器發出連線釋放報文,然後停止傳送資料;
- 伺服器接收到釋放報文後發出確認報文,然後將伺服器上未傳送完的資料傳送完;
- 伺服器資料傳輸完畢後,向客戶機傳送連線釋放報文;
- 客戶機接收到報文後,發出確認,然後等待一段時間後,釋放TCP連線
七、瀏覽器解析響應內容,處理和渲染
瀏覽器接收到HTTP響應,檢查HTTP狀態碼,根據狀態碼決定後續處理,進行渲染,呈現給使用者:
- 如果響應是HTML,瀏覽器啟動HTML解析器解析頁面,並請求html程式碼中的資源(如js、css、圖片等)
- 瀏覽器接收到 HTTP 資料包後的解析流程(解析 html、 詞法分析然後解析成 dom 樹、解析 css ⽣成 css 規則樹、合併成render 樹,然後layout 、 painting 渲染、複合圖層的合成、 GPU 繪製、外鏈資源的處理、 loaded 和 DOMContentLoaded 等)
- 如果響應是JSON資料,JavaScript程式碼處理資料並更新DOM或執行其他操
作。 - 進行後續資源的請求和載入(如CSS、JS檔案)
八、總結
瀏覽器中輸入URL返回頁面過程,具體分為7個步驟:
- 瀏覽器中輸入域名
- 解析域名,找到主機ip
- 瀏覽器與目標伺服器建立TCP連線。瀏覽器利用IP直接與網站主機通訊,三次握手、建立TCP連線。瀏覽器會以一個隨機埠向服務端的web程式80埠發起TCP連線
- 瀏覽器透過http協議向目標伺服器傳送請求。建立TCP連線後,瀏覽器向主機發起一個HTTP請求
- 伺服器響應請求,將對應資料返回給瀏覽器
- TCP釋放連結
- 瀏覽器解析響應內容,進行渲染,呈現給使用者
參考 瀏覽器中輸入URL到頁面返回的全過程、DNS域名解析服務、瀏覽器輸入url後執行的整個過程(詳細解析)、影子的知識文件