目錄
- 一、前言
- 二、解析 URL
- 三、瀏覽器封裝 HTTP 請(qǐng)求報(bào)文
- 四、DNS 域名解析獲取 IP 地址
- 五、建立 TCP 連接
- 六、瀏覽器發(fā)送請(qǐng)求
- 七、負(fù)責(zé)傳輸?shù)?IP 協(xié)議
- 八、使用 ARP 協(xié)議憑借 MAC 地址通信
- 九、服務(wù)器響應(yīng)請(qǐng)求
- 十、斷開 TCP 連接
- 十一、瀏覽器顯示界面
- 十二、總結(jié)
一、前言
在瀏覽器的地址欄輸入一個(gè) URL 后回車,背后到底發(fā)生了什么才能使得一個(gè)界面完美的展現(xiàn)在我們眼前?
今天講解的這道題目,由于其涉及大量網(wǎng)絡(luò)協(xié)議,可以非常直觀的看出諸位小伙伴對(duì)計(jì)算機(jī)網(wǎng)絡(luò)體系的整體把握程度,所以自然成為了各大公司的面試常客。
在瀏覽中輸入 URL 并且獲取響應(yīng)的過程,其實(shí)就是瀏覽器和該 URL 對(duì)應(yīng)的服務(wù)器的網(wǎng)絡(luò)通信過程。比如我們輸入 www.baidu.com
,那么會(huì)返回一個(gè)百度搜索的界面,這其實(shí)就是瀏覽器和百度服務(wù)器之間的網(wǎng)絡(luò)通信過程。瀏覽器就是客戶端,用于發(fā)出請(qǐng)求,而百度的服務(wù)器就是服務(wù)端,用于接收并響應(yīng)請(qǐng)求。
下面我們就來詳細(xì)講解這個(gè)龐大的網(wǎng)絡(luò)通信過程。
二、解析 URL
不知道有沒有同學(xué)會(huì)混淆域名和 URL 的概念,可以這樣理解,URL 就是我們輸入的網(wǎng)址,而網(wǎng)址里面含有域名。舉個(gè)例子:www.baidu.com/veal98
是一個(gè)網(wǎng)址,而 www.baidu.com
就是服務(wù)器的域名。
URL 各元素的組成如下(當(dāng)然,下述請(qǐng)求文件的路徑名可以省略):
![](/d/20211017/f38d8f75c302417e8b8240a66404e4c2.gif)
這個(gè) URL 請(qǐng)求的目標(biāo)服務(wù)器上的文件路徑就是:
![](/d/20211017/d9990f599718393c80fbeddfe918349f.gif)
那么首先,瀏覽器做的第一步就是解析 URL 得到里面的參數(shù),將域名和需要請(qǐng)求的資源分離開來,從而了解需要請(qǐng)求的是哪個(gè)服務(wù)器,請(qǐng)求的是服務(wù)器上什么資源等等。
三、瀏覽器封裝 HTTP 請(qǐng)求報(bào)文
對(duì) URL
進(jìn)行解析之后,瀏覽器確定了目標(biāo)服務(wù)器和文件名,接下來就需要根據(jù)這些消息封裝成一個(gè) HTTP 請(qǐng)求報(bào)文發(fā)送出去。舉個(gè) HTTP 請(qǐng)求報(bào)文的例子:
![](/d/20211017/924a3ca490110a10ec917c72f1e1aed1.gif)
解釋一下封裝,這是一個(gè)貫穿整個(gè)計(jì)算機(jī)網(wǎng)絡(luò)的概念。就是說發(fā)送端在層與層之間傳輸數(shù)據(jù)時(shí),每經(jīng)過一層必定會(huì)被打上一個(gè)該層所屬的首部信息。反之,接收端在層與層之間傳輸數(shù)據(jù)時(shí),每經(jīng)過一層就會(huì)把該層對(duì)應(yīng)的首部信息消去。
![](/d/20211017/dcf2ac071ecbd46d12791871ba8689ed.gif)
四、DNS 域名解析獲取 IP 地址
封裝好 HTTP 請(qǐng)求報(bào)文后,在正式還有一項(xiàng)準(zhǔn)備工作沒有做,那就是獲取目標(biāo)服務(wù)器的 IP 地址。
雖然解析得到了域名,理論瀏覽器已經(jīng)知道目標(biāo)服務(wù)器是誰(shuí)了。但是實(shí)際上,域名并不是目標(biāo)服務(wù)器真正意義上的地址,互聯(lián)網(wǎng)上每一臺(tái)計(jì)算機(jī)都被全世界唯一 IP 地址標(biāo)識(shí)著,但是 IP 地址并不方便記憶,所以才設(shè)計(jì)出了域名。
那么就需要解析域名獲取目標(biāo)服務(wù)器的 IP 地址。不然空有一個(gè)方便記憶的域名咋知道這個(gè)請(qǐng)求到底發(fā)送到哪里去呢。由域名轉(zhuǎn)換得到 IP 地址就是 DNS 協(xié)議做的事情,如下:
1)首先搜索瀏覽器的 DNS 緩存,緩存中維護(hù)著一張域名與 IP 地址的對(duì)應(yīng)表;
2)若沒有命中,則繼續(xù)搜索操作系統(tǒng)的 DNS 緩存;
3)若仍然沒有命中,則操作系統(tǒng)將域名發(fā)送至本地域名服務(wù)器,本地域名服務(wù)器查詢自己的 DNS 緩存,查找成功則返回結(jié)果(注意:主機(jī)和本地域名服務(wù)器之間的查詢方式是遞歸查詢);
4)若本地域名服務(wù)器的 DNS 緩存沒有命中,則本地域名服務(wù)器向上級(jí)域名服務(wù)器進(jìn)行查詢,通過以下方式進(jìn)行迭代查詢(注意:本地域名服務(wù)器和其他域名服務(wù)器之間的查詢方式是迭代查詢,防止根域名服務(wù)器壓力過大):
- 首先本地域名服務(wù)器向根域名服務(wù)器發(fā)起請(qǐng)求,根域名服務(wù)器是最高層次的,它并不會(huì)直接指明這個(gè)域名對(duì)應(yīng)的 IP 地址,而是返回頂級(jí)域名服務(wù)器的地址,也就是說給本地域名服務(wù)器指明一條道路,讓他去這里尋找答案
- 本地域名服務(wù)器拿到這個(gè)頂級(jí)域名服務(wù)器的地址后,就向其發(fā)起請(qǐng)求,獲取權(quán)限域名服務(wù)器的地址
- 本地域名服務(wù)器根據(jù)權(quán)限域名服務(wù)器的地址向其發(fā)起請(qǐng)求,最終得到該域名對(duì)應(yīng)的 IP 地址
4)本地域名服務(wù)器將得到的 IP 地址返回給操作系統(tǒng),同時(shí)自己將 IP 地址緩存起來
5)操作系統(tǒng)將 IP 地址返回給瀏覽器,同時(shí)自己也將 IP 地址緩存起來
6)至此,瀏覽器就得到了域名對(duì)應(yīng)的 IP 地址,并將 IP 地址緩存起來
配合下圖直觀理解:
![](/d/20211017/814fb9fdb93a79b05307a7d535992d91.gif)
需要注意的是,DNS 使用的是 UDP 協(xié)議,也就是說上面各種請(qǐng)求的轉(zhuǎn)發(fā),都是基于 UDP 這個(gè)無連接協(xié)議的。
五、建立 TCP 連接
獲取到了目標(biāo)服務(wù)器的 IP 地址之后,瀏覽器就知道我等下請(qǐng)求要發(fā)給誰(shuí)了,這個(gè)時(shí)候就可以開始發(fā)送封裝好了的 HTTP 請(qǐng)求報(bào)文了,那么既然需要發(fā)送請(qǐng)求,必然就需要 TCP 通過三次握手為瀏覽器和服務(wù)器之間建立可靠的連接,保證雙方都具有可靠的接收和發(fā)送能力。
三次握手過程如下圖:
![](/d/20211017/b555709f9c9500f42fe6bc84c2f32cfb.gif)
六、瀏覽器發(fā)送請(qǐng)求
TCP 三次握手完成后,瀏覽器與目標(biāo)服務(wù)器之間就建立了一個(gè)可靠的虛擬通道,于是瀏覽器就可以發(fā)送自己的 HTTP 請(qǐng)求了。
需要注意的是,HTTP 請(qǐng)求報(bào)文或者響應(yīng)報(bào)文在 TCP 連接通道上進(jìn)行傳輸?shù)臅r(shí)候,由于這些報(bào)文比較大,為了更容易和準(zhǔn)確可靠的傳輸,TCP 會(huì)將 HTTP 報(bào)文按序號(hào)分割成若干報(bào)文段并加上 TCP 首部,分別進(jìn)行傳輸。接收方在收到這些報(bào)文段后,按照序號(hào)以原來的順序重組 HTTP 報(bào)文。
七、負(fù)責(zé)傳輸?shù)?IP 協(xié)議
實(shí)際上,TCP 在三次握手建立連接、四次握手?jǐn)嚅_連接、以及連接建立過程中的收發(fā)數(shù)據(jù)(TCP 報(bào)文段)等各階段操作時(shí),都是通過 IP 協(xié)議進(jìn)行傳輸?shù)?,IP 協(xié)議將這些階段的數(shù)據(jù)添加 IP 首部封裝成 IP 數(shù)據(jù)報(bào)再進(jìn)行傳輸。
IP 數(shù)據(jù)報(bào)的首部存有源 IP 地址和 目標(biāo) IP 地址。所謂源 IP 地址 就是發(fā)送方的 IP 地址;目標(biāo) IP 地址就是通過 DNS 域名解析得到的目標(biāo)服務(wù)器的 IP 地址。
事實(shí)上,IP 協(xié)議身處的網(wǎng)絡(luò)層規(guī)定的是:數(shù)據(jù)報(bào)要通過怎樣的路徑(傳輸路線)才能到達(dá)對(duì)方計(jì)算機(jī),并傳送給對(duì)方。不理解這句話的詳細(xì)解釋馬上就來,繼續(xù)往下讀。
八、使用 ARP 協(xié)議憑借 MAC 地址通信
上面說了,IP 協(xié)議的作用是把各種數(shù)據(jù)包傳送給對(duì)方,而要保證確實(shí)傳送到對(duì)方那里,則需要滿足各類條件,其中必要的兩個(gè)就是 IP 地址 和 MAC 地址。
MAC 地址也是用來唯一標(biāo)識(shí)一個(gè)接入互聯(lián)網(wǎng)的設(shè)備的,可能不禁有小伙伴要問,既然網(wǎng)絡(luò)層已經(jīng)有了唯一標(biāo)識(shí)的 IP 地址,為啥還需要 MAC 地址?
看下面這幅圖,在網(wǎng)絡(luò)上,通信的雙方在同一局域網(wǎng)內(nèi)的情況是很少見的,通常是需要多臺(tái)計(jì)算機(jī)和網(wǎng)絡(luò)設(shè)備的中轉(zhuǎn)才能連接到對(duì)方。而在進(jìn)行中轉(zhuǎn)時(shí),就需要利用下一站中轉(zhuǎn)設(shè)備的 MAC 地址來搜索下一個(gè)中轉(zhuǎn)目標(biāo)。
![](/d/20211017/1fa57ef5c75e63a702b310bbc97385a6.gif)
- 網(wǎng)絡(luò)層指定了從哪個(gè)主機(jī)(「源 IP 地址」)發(fā)送到哪個(gè)主機(jī)(「目的 IP 地址」)。源 IP 地址和目標(biāo) IP 地址在傳輸過程中是不會(huì)變化的
- 而數(shù)據(jù)鏈路層則是根據(jù) MAC 地址在一個(gè)接一個(gè)的區(qū)間中進(jìn)行傳輸?shù)?,每個(gè)區(qū)間內(nèi)的出發(fā)地址即「源 MAC 地址」,每個(gè)區(qū)間內(nèi)的目的地址即「目的 MAC 地址」。顯然,隨著數(shù)據(jù)的傳輸,源 MAC 地址和目的 MAC 地址會(huì)不斷的發(fā)生變化
比如上圖,網(wǎng)絡(luò)層告知了 1-2-3 路線,也就是說指明了這幾個(gè)路由器的 IP 地址。那么數(shù)據(jù)鏈路層就會(huì)根據(jù)這幾個(gè) IP 地址對(duì)應(yīng)的 MAC 地址依次找到 1、2、3,并在他們之間傳輸數(shù)據(jù)。
這么說吧,舉個(gè)形象點(diǎn)的例子:我們把數(shù)據(jù)鏈路層當(dāng)成乘坐高鐵從蘇州到南京,再在南京轉(zhuǎn)乘到北京,再在北京轉(zhuǎn)乘到西藏的旅客,那么網(wǎng)絡(luò)層就相當(dāng)于每個(gè)車站的工作人員,在數(shù)據(jù)鏈路層每次轉(zhuǎn)乘時(shí),網(wǎng)絡(luò)層為其購(gòu)買了一張標(biāo)有下一個(gè) MAC 地址的車票。因此,即使旅客(數(shù)據(jù)鏈路層)不知道其最終目的地也沒有關(guān)系,工作人員(網(wǎng)絡(luò)層)會(huì)給你做出指引。
實(shí)際上,網(wǎng)絡(luò)層做出指引的過程,我們將其稱為路由控制,其中又涉及到了路由協(xié)議比如 OSPF 等
![](/d/20211017/389e26a293b5f0260ef3153bbec1e402.gif)
那么,將 IP 地址轉(zhuǎn)化為 MAC 地址,從而在數(shù)據(jù)鏈路層精確的傳輸數(shù)據(jù)的協(xié)議就是 ARP 協(xié)議。
ARP 是借助 ARP 請(qǐng)求與 ARP 響應(yīng)兩種類型的包確定 MAC 地址的。并且每個(gè)主機(jī)都有一個(gè) ARP 高速緩存,里面有本局域網(wǎng)上的各主機(jī)和路由器的 IP 地址到 MAC 地址的映射表。
如下圖所示,假定主機(jī) A 向同一鏈路上的主機(jī) B 發(fā)送 IP 數(shù)據(jù)報(bào),已知主機(jī) A 和主機(jī) B 的 IP 地址,它們互不知道對(duì)方的 MAC 地址:
![](/d/20211017/0d1d3f45794732838bc68167c8bdab1e.gif)
1)首先,主機(jī) A 為了獲得主機(jī) B 的 MAC 地址,它會(huì)先去查詢自己的 ARP 高速緩存中有沒有主機(jī) B 的相關(guān)記錄;
2)如果主機(jī) A 的 ARP 高速緩存中沒有主機(jī) B 的 IP 地址到 MAC 地址的映射,主機(jī) A 就會(huì)通過廣播的方式發(fā)送 ARP 請(qǐng)求包(該包攜帶自己的 IP 地址 和 MAC 地址 以及 目標(biāo)主機(jī)的 IP 地址),表明自己想要獲得主機(jī) B 的 MAC 地址;
2) 由于廣播請(qǐng)求可以被同一個(gè)鏈路上的所有主機(jī)或路由器接收,因此如果這條鏈路上某個(gè)主機(jī)或路由的 IP 地址與這個(gè) ARP 請(qǐng)求包中包含的目標(biāo)主機(jī)的 IP 地址相同,那么這個(gè)節(jié)點(diǎn)就將自己的 MAC 地址塞入 ARP 響應(yīng)包中返回給主機(jī) A;
![](/d/20211017/1635322f3aae6779b6a30f0fdc954520.gif)
當(dāng)然,ARP 響應(yīng)包是以單播的形式進(jìn)行發(fā)送的,畢竟 ARP 請(qǐng)求包中已經(jīng)包含了主機(jī) A 的 IP 地址,所以主機(jī) B 非常清楚這個(gè)響應(yīng)包應(yīng)該發(fā)送給誰(shuí)。
大部分網(wǎng)絡(luò)協(xié)議在設(shè)計(jì)的時(shí)候,都是保持極度克制的,不需要的交互就砍掉,能合并的信息就合并,能不用廣播就用單播,以此讓帶寬變得更多讓網(wǎng)絡(luò)變得更快。
3)主機(jī) A 在收到主機(jī) B 發(fā)過來的 ARP 響應(yīng)包后,向其 ARP 高速緩存中寫入主機(jī) B 的 IP 地址到 MAC 地址的映射。
![](/d/20211017/8df8121b7f1dcb51326436f213d21350.gif)
當(dāng)然,緩存是有一定期限的,超過這個(gè)期限,緩存的內(nèi)容將被清空。這也使得即使 MAC 地址和 IP 地址的映射關(guān)系發(fā)生了變化,也依然能夠正確的將數(shù)據(jù)包發(fā)送給目標(biāo)地址。
九、服務(wù)器響應(yīng)請(qǐng)求
瀏覽器的 HTTP 請(qǐng)求報(bào)文通過 TCP 三次握手建立的連接通道被切分成若干報(bào)文段分別發(fā)送給服務(wù)器,服務(wù)器在收到這些報(bào)文段后,按照序號(hào)以原來的順序重組 HTTP 請(qǐng)求報(bào)文。然后處理并返回一個(gè) HTTP 響應(yīng)。當(dāng)然,HTTP 響應(yīng)報(bào)文也要經(jīng)過和 HTTP 請(qǐng)求報(bào)文一樣的過程。
看下方這個(gè)圖回顧一下(圖片來源《圖解 HTTP》):
![](/d/20211017/0540f7886ec1fdb67f786e863f8e5e89.gif)
十、斷開 TCP 連接
瀏覽器和服務(wù)器都不再需要發(fā)送數(shù)據(jù)后,四次揮手?jǐn)嚅_ TCP 連接
十一、瀏覽器顯示界面
瀏覽器接收到服務(wù)器返回的數(shù)據(jù)包,根據(jù)瀏覽器的渲染機(jī)制對(duì)相應(yīng)的數(shù)據(jù)進(jìn)行渲染
十二、總結(jié)
屏蔽掉底層細(xì)節(jié),籠統(tǒng)的總結(jié)一下上述過程:
應(yīng)用層:
- 瀏覽器封裝 HTTP 請(qǐng)求報(bào)文
- DNS 解析域名獲得目標(biāo)服務(wù)器地址
傳輸層:
- 建立連接
- 把應(yīng)用層傳過來的 HTTP 請(qǐng)求報(bào)文進(jìn)行分割,并在各個(gè)報(bào)文上打上標(biāo)記序號(hào)及端口號(hào)轉(zhuǎn)發(fā)給網(wǎng)絡(luò)層
網(wǎng)絡(luò)層:
- 利用 ARP 協(xié)議根據(jù) IP 地址獲取作為通信目的地的 MAC 地址后轉(zhuǎn)發(fā)給鏈路層
服務(wù)端在鏈路層收到數(shù)據(jù),按序往上層發(fā)送,一直到應(yīng)用層接收到瀏覽器發(fā)送來的 HTTP 請(qǐng)求報(bào)文,然后處理該請(qǐng)求并返回 HTTP 響應(yīng)報(bào)文,瀏覽器接收到響應(yīng)報(bào)文之后解析渲染界面。最后 TCP 斷開連接。
以上就是解析在瀏覽器地址欄輸入一個(gè)URL后發(fā)生了什么的詳細(xì)內(nèi)容,更多關(guān)于在瀏覽器地址欄輸入一個(gè)URL的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
您可能感興趣的文章:- 使用JavaScript解析URL的方法示例
- JS解析url查詢參數(shù)的簡(jiǎn)單代碼
- php解析url并得到url中的參數(shù)及獲取url參數(shù)的四種方式
- php使用parse_url和parse_str解析URL