瀏覽器上面輸入U(xiǎn)RL敲擊回車后都發(fā)生了什么
這哥問(wèn)題是一個(gè)常被用作面試題的問(wèn)題下面我們來(lái)細(xì)說(shuō)一下這個(gè)流程和相關(guān)概念
URL 解析
URL,統(tǒng)一資源定位符,是用來(lái)表示從互聯(lián)網(wǎng)上得到的資源位置和訪問(wèn)這些資源的方法,俗稱網(wǎng)址!互聯(lián)網(wǎng)上的所有資源,都有一個(gè)唯一確定的URL。URL的一般形式由一下四個(gè)部分組成:
<協(xié)議>://<主機(jī)>:<端口>/<路徑>
URL的第一部分是最左邊的<協(xié)議>。這里的<協(xié)議>就是指出使用什么協(xié)議來(lái)獲取萬(wàn)維網(wǎng)文檔。現(xiàn)在最常用的協(xié)議就是http(超文本傳輸協(xié)議HTTP),其次就是ftp(文件傳輸協(xié)議FTP)。在協(xié)議后面的:// 是規(guī)定的格式。它的右邊是第二部分<主機(jī)>,它指出這個(gè)萬(wàn)維網(wǎng)文檔是在哪一臺(tái)主機(jī)上。這里的<主機(jī)>就是指該主機(jī)在互聯(lián)網(wǎng)上的域名 。在后面是第三部分和第四部分<端口>和<路徑>,有時(shí)可以省略。如果是采用http協(xié)議訪問(wèn)萬(wàn)維網(wǎng)文檔,如果省略端口,走會(huì)訪問(wèn)默認(rèn)端口80,如果省略路徑,則URL就指到互聯(lián)網(wǎng)上的某個(gè)主頁(yè)(home page)。而URL解析,就是當(dāng)用戶輸入U(xiǎn)RL并回車后,瀏覽器對(duì)拿到的URL進(jìn)行識(shí)別,抽取出域名字段,比如https://www.baidu.com,它的域名就是www.baidu.com,拿到域名后,就會(huì)順利進(jìn)行第二步了,就是DNS域名解析!
圖片
DNS 域名解析
域名系統(tǒng)DNS(Domain Name System)是互聯(lián)網(wǎng)使用的命名系統(tǒng),用來(lái)把便于人們使用的機(jī)器名轉(zhuǎn)換為IP地址。用戶與互聯(lián)網(wǎng)上的某臺(tái)主機(jī)通信時(shí),必須要知道對(duì)方的IP地址。然而用戶很難記住長(zhǎng)達(dá)32位的二進(jìn)制主機(jī)地址。及時(shí)是點(diǎn)分十進(jìn)制IP地址也并不容易記憶。但是在應(yīng)用層為了方便用戶記憶各種網(wǎng)絡(luò)應(yīng)用,連接在互聯(lián)網(wǎng)上的主機(jī)不僅有IP地址,而且還有便于用戶記憶的主機(jī)名字(域名)。域名系統(tǒng)DNS能夠把互聯(lián)網(wǎng)上的主機(jī)名字轉(zhuǎn)換為IP地址。既然互聯(lián)網(wǎng)上的每一臺(tái)主機(jī)都有主機(jī)名字,那么為什么機(jī)器在處理IP數(shù)據(jù)報(bào)的時(shí)候要使用IP地址而不是用域名呢?簡(jiǎn)單來(lái)說(shuō),這是因?yàn)镮P地址的長(zhǎng)度是固定的32位(如果是IPv6地址,那就是固定的128位,也是定長(zhǎng)的),而域名的長(zhǎng)度并不是固定的,機(jī)器處理起來(lái)比較困難。注意,可以在瀏覽器中輸入域名得出網(wǎng)頁(yè)內(nèi)容,也可以輸入對(duì)應(yīng)的IP地址得到網(wǎng)頁(yè)內(nèi)容。雖然得出的內(nèi)容是一樣的,但調(diào)用的過(guò)程不一樣,輸入IP地址是直接從主機(jī)上調(diào)用內(nèi)容,輸入域名是通過(guò)對(duì)應(yīng)的域名解析服務(wù)器指向?qū)?yīng)的主機(jī)IP地址,在從主機(jī)中調(diào)用網(wǎng)址的內(nèi)容。
圖片
建立 TCP 連接
第一次握手:客戶端向服務(wù)器端發(fā)送請(qǐng)求(SYN=1) 等待服務(wù)器響應(yīng);第二次握手:服務(wù)器收到請(qǐng)求并確認(rèn),回復(fù)一個(gè)指令(SYN=1,ACK=1);第三次握手:客戶端收到服務(wù)器的回復(fù)指令并返回確認(rèn)(ACK=1)。
圖片
這里我又有一個(gè)問(wèn)題來(lái)了,為什么A最后還要發(fā)送一次確認(rèn)呢?請(qǐng)讀者稍加思考一下!
這主要是為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了B,因而產(chǎn)生錯(cuò)誤!所謂的已失效的請(qǐng)求報(bào)文段是這樣產(chǎn)生的。考慮一種正常情況,A發(fā)出連接請(qǐng)求,但因連接請(qǐng)求報(bào)文丟失而未收到確認(rèn)。于是A在重傳一次連接請(qǐng)求。后來(lái)收到了來(lái)自服務(wù)器的連接請(qǐng)求確認(rèn),建立了連接。數(shù)據(jù)傳輸完畢后,就通過(guò)四次揮手釋放了連接。在該過(guò)程中,A共發(fā)出了兩個(gè)連接請(qǐng)求報(bào)文段,其中第一個(gè)丟失,第二個(gè)達(dá)到了B,沒(méi)有已失效的連接請(qǐng)求報(bào)文段。
現(xiàn)假定出現(xiàn)一種異常情況,即A發(fā)出的第一個(gè)連接請(qǐng)求報(bào)文段并沒(méi)有丟失,而是在某些網(wǎng)絡(luò)結(jié)點(diǎn)長(zhǎng)時(shí)間滯留了,以致延誤到連接釋放以后的某個(gè)時(shí)間才達(dá)到B。本來(lái)這是一個(gè)早已失效的報(bào)文段,但B收到此失效的連接請(qǐng)求報(bào)文段后,就誤認(rèn)為是A又發(fā)出了一次新的連接請(qǐng)求。于是就想A發(fā)出確認(rèn)連接報(bào)文段,同意建立連接。假定不采用三次握手,那么只要B發(fā)出確認(rèn),新的連接就建立了。由于現(xiàn)在A并沒(méi)有發(fā)出建立連接的請(qǐng)求,因此不會(huì)理睬B的確認(rèn),也不會(huì)向B發(fā)送數(shù)據(jù)。但B卻認(rèn)為新的運(yùn)輸連接已經(jīng)建立了,并一直等待A發(fā)送數(shù)據(jù)。于是B的資源就這樣白白浪費(fèi)了。
發(fā)送 HTTP 請(qǐng)求
HTTP協(xié)議定義了瀏覽器怎樣向萬(wàn)維網(wǎng)服務(wù)器請(qǐng)求萬(wàn)維網(wǎng)文檔,以及服務(wù)器怎樣把文檔傳送給瀏覽器。從層次的角度看,HTTP是面向事務(wù)的應(yīng)用層協(xié)議。HTTP有兩類報(bào)文:
(1)請(qǐng)求報(bào)文——從客戶端向服務(wù)器發(fā)送請(qǐng)求報(bào)文。如下圖所示。
(2)響應(yīng)報(bào)文——從服務(wù)器到客戶端的回答。
圖片
HTTP請(qǐng)求報(bào)文有三部分組成,即請(qǐng)求行,首部行和實(shí)體主體三部分組成。請(qǐng)求報(bào)文的第一行,請(qǐng)求行只有三個(gè)內(nèi)容,即方法,請(qǐng)求資源的URL以及HTTP的版本。這里的方法就是對(duì)所請(qǐng)求的對(duì)象進(jìn)行操作這些方法實(shí)際上也就是一些命令。
常見(jiàn)請(qǐng)求報(bào)文的方法
方法(操作) | 意義 |
OPTION | 請(qǐng)求一些選項(xiàng)的信息 |
GET | 請(qǐng)求讀取由URL所標(biāo)志的信息 |
HEAD | 請(qǐng)求讀取由URL所標(biāo)志的信息的首部 |
CONNECT | 用于代理服務(wù)器 |
POST | 給服務(wù)器添加信息 |
PUT | 在指明的URL下存儲(chǔ)一個(gè)文檔 |
DELETE | 刪除指明的URL所標(biāo)志的資源 |
TRACE | 用來(lái)進(jìn)行環(huán)回測(cè)試的請(qǐng)求報(bào)文 |
例如下面是一個(gè)HTTP的請(qǐng)求報(bào)文的開始行的格式,由方法,域名以及HTTP的版本構(gòu)成。注意(方法與域名之間含空格,域名與HTTP版本之間也含空格)。
GET http://www.lovsh.com/dir/index.html HTTP/1.1
服務(wù)器處理相關(guān)的請(qǐng)求
接受HTTP報(bào)文后,會(huì)對(duì)連接進(jìn)行處理,對(duì)HTTP協(xié)議進(jìn)行解析(請(qǐng)求方法、域名、路徑等),并且進(jìn)行一些驗(yàn)證:
驗(yàn)證是否配置虛擬主機(jī)驗(yàn)證虛擬主機(jī)是否接受此方法驗(yàn)證該用戶可以使用該方法(根據(jù) IP 地址、身份信息等)重定向假如服務(wù)器配置了 HTTP 重定向,就會(huì)返回一個(gè) 301永久重定向響應(yīng),瀏覽器就會(huì)根據(jù)響應(yīng),重新發(fā)送 HTTP 請(qǐng)求(重新執(zhí)行上面的過(guò)程)。URL 重寫然后會(huì)查看 URL 重寫規(guī)則,如果請(qǐng)求的文件是真實(shí)存在的,比如圖片、html、css、js文件等,則會(huì)直接把這個(gè)文件返回。否則服務(wù)器會(huì)按照規(guī)則把請(qǐng)求重寫到 一個(gè) REST 風(fēng)格的 URL 上。然后根據(jù)動(dòng)態(tài)語(yǔ)言的腳本,來(lái)決定調(diào)用什么類型的動(dòng)態(tài)文件解釋器來(lái)處理這個(gè)請(qǐng)求。
圖片
返回響應(yīng)的結(jié)果
服務(wù)器每收到一個(gè)請(qǐng)求報(bào)文后,對(duì)應(yīng)的都會(huì)回復(fù)一個(gè)響應(yīng)報(bào)文。HTTP的響應(yīng)報(bào)文由狀態(tài)行,首部行以及實(shí)體主體組成,一般用開始行是請(qǐng)求行還是狀態(tài)行來(lái)區(qū)分是請(qǐng)求報(bào)文還是響應(yīng)報(bào)文!
響應(yīng)報(bào)文的第一行就是狀態(tài)行,狀態(tài)行包括版本,狀態(tài)碼以及短語(yǔ)組成。狀態(tài)碼都是三位數(shù)字構(gòu)成的,分為5大類,原先有33種,后來(lái)又增加了幾種。這5大類的狀態(tài)碼都是以不同的數(shù)字開頭的。
狀態(tài)碼 | 意義 |
1xx | 表示通知信息,如請(qǐng)求收到了或正在進(jìn)行處理 |
2xx | 表示成功,如接受或知道了 |
3xx | 表示重定向,如要完成請(qǐng)求還必須采取進(jìn)一步的行動(dòng) |
4xx | 表示客戶的差錯(cuò),如請(qǐng)求中有錯(cuò)誤的語(yǔ)法或不能完成 |
5xx | 表示服務(wù)器的錯(cuò)誤,如服務(wù)器失效無(wú)法完成請(qǐng)求 |
斷開 TCP 連接
第一次揮手:客戶端向服務(wù)器發(fā)送連接釋放報(bào)文段(FIN=1),等待服務(wù)器響應(yīng);
第二次揮手:服務(wù)器收到連接釋放報(bào)文段并發(fā)出確認(rèn)(ACK=1),客戶端到服務(wù)器的連接關(guān)閉,此時(shí)TCP處理半關(guān)閉狀態(tài),需要等到服務(wù)器向客戶端發(fā)送數(shù)據(jù)結(jié)束;
第三次揮手:服務(wù)器向客戶端發(fā)送連接釋放報(bào)文段(FIN=1,ACK=1),并等待客戶端的確認(rèn);
第四次揮手:客戶端收到服務(wù)器的連接釋放報(bào)文段并給出確認(rèn)(ACK=1),連接釋放。
圖片
瀏覽器解析渲染頁(yè)面
HTMl解析與頁(yè)面渲染的過(guò)程如下所示:
- 瀏覽器獲取到 html 資源后開始解析 html (dom tree)
- 解析到 css 后根據(jù) css 生成 css 規(guī)則樹 (style rules).
- 在 dom 樹和 css 規(guī)則樹都生成完后,通過(guò) dom 樹和 css 規(guī)則樹生成渲染樹( render tree )
- 渲染樹構(gòu)建完成后,瀏覽器開始計(jì)算元素的大小和位置( layout )
- 根據(jù)計(jì)算好的節(jié)點(diǎn)信息將內(nèi)容繪制到屏幕上( painting )
圖片
注意:
瀏覽器為了提升性能,在 URL 解析之后,實(shí)際會(huì)先查詢是否有緩存,如果緩存命中,則直接返回緩存資源。
如果是 HTTPS 協(xié)議,在建立 TCP 連接之后,還需要進(jìn)行 SSL/TLS 握手過(guò)程,以協(xié)商出一個(gè)會(huì)話密鑰,用于消息加密,提升安全性。