總體來說分為以下幾個(gè)過程:
- 輸入地址
- DNS 解析:將域名解析成IP地址
- TCP 連接:TCP三次握手
- 發(fā)送HTTP請(qǐng)求
- 服務(wù)器處理請(qǐng)求并返回HTTP報(bào)文
- 瀏覽器解析渲染頁面
- 斷開連接: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
。 -
host
- 定義域主機(jī)(http
的默認(rèn)主機(jī)是www
) -
domain
- 定義因特網(wǎng)域名牢贸,比如w3school.com.cn
-
port
- 定義主機(jī)上的端口號(hào)(http
的默認(rèn)端口號(hào)是80) -
path
- 定義服務(wù)器上的路徑(如果省略竹观,則文檔必須位于網(wǎng)站的根目錄中) -
filename
- 定義文檔/資源的名稱
輸入地址
當(dāng)我們開始在瀏覽器中輸入網(wǎng)址的時(shí)候,瀏覽器其實(shí)就已經(jīng)在智能的匹配可能得了潜索,他會(huì)從歷史記錄臭增,書簽等地方,找到已經(jīng)輸入的字符串可能對(duì)應(yīng)的URL竹习,然后給出智能提示誊抛,讓你可以補(bǔ)全URL地址。對(duì)于chrome瀏覽器整陌,他甚至?xí)苯訌木彺嬷邪丫W(wǎng)頁展示出來拗窃,就是說,你還沒有按下enter
蔓榄,頁面就出來了并炮。
域名解析(DNS)
在瀏覽器輸入網(wǎng)址后,首先要經(jīng)過域名解析甥郑,因?yàn)闉g覽器并不能直接通過域名找到對(duì)應(yīng)的服務(wù)器逃魄,而是要通過IP地址。大家這里或許會(huì)有個(gè)疑問----計(jì)算機(jī)既可以被賦予IP地址澜搅,也可以被賦予主機(jī)名和域名伍俘。比如 www.hackr.jp
。那怎么不一開始就賦予個(gè)IP地址勉躺?這樣就可以省去解析麻煩癌瘾。我們先來了解下什么是 IP 地址。
1.IP 地址
IP地址是指互聯(lián)網(wǎng)協(xié)議地址饵溅,是IP Address的縮寫妨退。IP地址是IP協(xié)議提供的一種統(tǒng)一的地址格式,它為互聯(lián)網(wǎng)上的每一個(gè)網(wǎng)絡(luò)和每一臺(tái)主機(jī)分配一個(gè)邏輯地址蜕企,以此來屏蔽物理地址的差異咬荷。IP地址是一個(gè)32位的二進(jìn)制數(shù),比如127.0.0.1為本機(jī)IP轻掩。
域名就相當(dāng)于IP地址喬裝打扮的偽裝者幸乒,帶著一副面具。它的作用就是便于記憶和溝通的一組服務(wù)器的地址唇牧。用戶通常使用主機(jī)名或域名來訪問對(duì)方的計(jì)算機(jī)罕扎,而不是直接通過IP地址訪問聚唐。因?yàn)榕cIP地址的一組純數(shù)字相比,用字母配合數(shù)字的表示形式來指定計(jì)算機(jī)名更符合人類的記憶習(xí)慣腔召。但要讓計(jì)算機(jī)去理解名稱杆查,相對(duì)而言就變得困難了。因?yàn)橛?jì)算機(jī)更擅長(zhǎng)處理一長(zhǎng)串?dāng)?shù)字宴咧。為了解決上述的問題根灯,DNS服務(wù)應(yīng)運(yùn)而生。
2.什么是域名解析
DNS協(xié)議提供通過域名查找IP地址掺栅,或逆向從IP地址反查域名的服務(wù)烙肺。DNS是一個(gè)網(wǎng)絡(luò)服務(wù)器,我們的域名解析簡(jiǎn)單來說就是在DNS上記錄一條信息記錄氧卧。
例如baidu.com 220.114.23.56
(服務(wù)器外網(wǎng)IP地址)80(服務(wù)器端口號(hào))
3. 瀏覽器如何通過域名去查詢URL對(duì)應(yīng)的IP
- 瀏覽器緩存:瀏覽器會(huì)按照一定的頻率緩存 DNS 記錄桃笙。所以首先會(huì)在瀏覽器的緩存中查找是否有該域名對(duì)應(yīng)的IP地址。在chrome可以通過地址欄中輸入
chrome://net-internals/#dns
查看緩存的當(dāng)前狀態(tài)沙绝。 - 操作系統(tǒng)緩存:如果瀏覽器緩存中找不到需要的 DNS 記錄搏明,那就去操作系統(tǒng)中找。
- 路由緩存:有些路由器也有DNS緩存的功能闪檬,訪問過的域名會(huì)存在路由器上星著。
- ISP的DNS服務(wù)器:ISP是互聯(lián)網(wǎng)服務(wù)提供商(
Internet Service Provider
)的簡(jiǎn)稱,ISP有專門的DNS服務(wù)器應(yīng)對(duì)DNS查詢請(qǐng)求粗悯。在本地查找不到的情況下虚循,就會(huì)向ISP進(jìn)行查詢,ISP會(huì)在當(dāng)前服務(wù)器的緩存內(nèi)查找是否有記錄样傍。 - 根服務(wù)器:ISP的DNS服務(wù)器還找不到的話横缔,它就會(huì)向根服務(wù)器發(fā)出請(qǐng)求,進(jìn)行遞歸查詢(DNS 服務(wù)器先問根域名服務(wù)器
.com
域名服務(wù)器的 IP 地址衫哥,然后再問.baidu
域名服務(wù)器茎刚,依次類推)
小結(jié)
瀏覽器通過向DNS服務(wù)器發(fā)送域名,DNS服務(wù)器查詢到與域名相對(duì)應(yīng)的IP地址撤逢,然后返回給瀏覽器膛锭,瀏覽器再將IP地址打在協(xié)議上,同時(shí)請(qǐng)求參數(shù)也會(huì)在協(xié)議搭載蚊荣,然后一并發(fā)送給對(duì)應(yīng)的服務(wù)器初狰。接下來介紹向服務(wù)器發(fā)送HTTP請(qǐng)求階段,HTTP請(qǐng)求分為三個(gè)部分:TCP三次握手妇押、http請(qǐng)求響應(yīng)信息跷究、關(guān)閉TCP連接姓迅。
TCP 三次握手
在客戶端發(fā)送數(shù)據(jù)之前會(huì)發(fā)起TCP三次握手用以同步客戶端和服務(wù)端的序列號(hào)和確認(rèn)號(hào)敲霍,并交換 TCP 窗口大小信息俊马。
TCP 三次握手的過程如下:
- 客戶端發(fā)送一個(gè)帶SYN=1,Seq=X的數(shù)據(jù)包到服務(wù)器端口(第一次握手肩杈,由瀏覽器發(fā)起柴我,告訴服務(wù)器我要發(fā)送請(qǐng)求了)
- 服務(wù)器發(fā)回一個(gè)帶SYN=1,ACK=X+1扩然,Seq=Y 的響應(yīng)包以示傳達(dá)確認(rèn)信息(第二次握手艘儒,由服務(wù)器發(fā)起,告訴瀏覽器我準(zhǔn)備接受了夫偶,你趕緊發(fā)送吧)
- 客戶端再回傳一個(gè)帶ACK=Y+1界睁, Seq=Z的數(shù)據(jù)包,代表“握手結(jié)束”(第三次握手兵拢,由瀏覽器發(fā)送翻斟,告訴服務(wù)器,我馬上就發(fā)了说铃,準(zhǔn)備接受吧)
標(biāo)識(shí)位(TCP FLAG)
TCP的頭部固定有20個(gè)字節(jié)访惜,其中分配了6bits給TCP FLAG,組合起來用來表示當(dāng)前包的類型腻扇。分別是:
- URG:緊急指針债热,用于將要發(fā)送的包標(biāo)識(shí)為“緊急”,這意味著不必等待前段數(shù)據(jù)被響應(yīng)處理完即可發(fā)送給接收端幼苛。
- ACK:確認(rèn)標(biāo)識(shí)窒篱,用于表示對(duì)數(shù)據(jù)包的成功接收。
- PSH:推送標(biāo)識(shí)蚓峦,表示這個(gè)數(shù)據(jù)包應(yīng)該被立即發(fā)送舌剂,不需要等待額外的數(shù)據(jù)。
- RST:
reset
標(biāo)識(shí)暑椰,用來異常關(guān)閉連接霍转。 - SYN:同步標(biāo)識(shí),表示TCP連接已初始化一汽。
- FIN:完成標(biāo)識(shí)避消,用于拆除上一個(gè)SYN標(biāo)識(shí)。一個(gè)完整的TCP連接過程一定會(huì)有SYN和FIN包召夹。
為啥需要三次握手
三次握手”的目的是“為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了服務(wù)端岩喷,因而產(chǎn)生錯(cuò)誤”。
“已失效的連接請(qǐng)求報(bào)文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個(gè)連接請(qǐng)求報(bào)文段并沒有丟失监憎,而是在某個(gè)網(wǎng)絡(luò)結(jié)點(diǎn)長(zhǎng)時(shí)間的滯留了纱意,以致延誤到連接釋放以后的某個(gè)時(shí)間才到達(dá)server。本來這是一個(gè)早已失效的報(bào)文段鲸阔。但server收到此失效的連接請(qǐng)求報(bào)文段后偷霉,就誤認(rèn)為是client再次發(fā)出的一個(gè)新的連接請(qǐng)求迄委。于是就向client發(fā)出確認(rèn)報(bào)文段,同意建立連接类少。
假設(shè)不采用“三次握手”叙身,那么只要server發(fā)出確認(rèn),新的連接就建立了硫狞。由于現(xiàn)在client并沒有發(fā)出建立連接的請(qǐng)求信轿,因此不會(huì)理睬server的確認(rèn),也不會(huì)向server發(fā)送數(shù)據(jù)残吩。但server卻以為新的運(yùn)輸連接已經(jīng)建立财忽,并一直等待client發(fā)來數(shù)據(jù)。這樣泣侮,server的很多資源就白白浪費(fèi)掉了定罢。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生。例如剛才那種情況旁瘫,client不會(huì)向server的確認(rèn)發(fā)出確認(rèn)祖凫。server由于收不到確認(rèn),就知道client并沒有要求建立連接酬凳。主要目的防止server端一直等待惠况,浪費(fèi)資源。
發(fā)送 HTTP 請(qǐng)求
TCP三次握手結(jié)束后宁仔,開始發(fā)送HTTP請(qǐng)求報(bào)文稠屠。
請(qǐng)求報(bào)文由請(qǐng)求行、請(qǐng)求頭翎苫、請(qǐng)求體三個(gè)部分組成权埠,如下圖所示:
請(qǐng)求行包含請(qǐng)求方法、URL煎谍、協(xié)議版本
- 請(qǐng)求方法包含8種:GET攘蔽、POST、PUT呐粘、DELETE满俗、PATCH、HEAD作岖、OPTIONS唆垃、TRACE。
- URL 即請(qǐng)求地址痘儡,由 <協(xié)議>://<主機(jī)>:<端口>/<路徑>?<參數(shù)> 組成
- 協(xié)議版本即
http
版本號(hào)
POST /chapter17/user.html HTTP/1.1
請(qǐng)求頭包含請(qǐng)求的附加信息辕万,由關(guān)鍵字/值對(duì)組成,每行一對(duì),關(guān)鍵字和值用英文冒號(hào)“:”分隔渐尿。
請(qǐng)求頭部通知服務(wù)器有關(guān)于客戶端請(qǐng)求的信息价捧。它包含許多有關(guān)的客戶端環(huán)境和請(qǐng)求正文的有用信息。其中比如:Host
涡戳,表示主機(jī)名,虛擬主機(jī)脯倚;Connection,HTTP/1.1
增加的渔彰,使用keepalive
,即持久連接推正,一個(gè)連接可以發(fā)多個(gè)請(qǐng)求恍涂;User-Agent
,請(qǐng)求發(fā)出者植榕,兼容性以及定制化需求再沧。
請(qǐng)求體,可以承載多個(gè)請(qǐng)求參數(shù)的數(shù)據(jù)尊残,包含回車符炒瘸、換行符和請(qǐng)求數(shù)據(jù),并不是所有請(qǐng)求都具有請(qǐng)求數(shù)據(jù)寝衫。
name=tom&password=1234&realName=tomson
服務(wù)器處理請(qǐng)求并返回 HTTP 報(bào)文
每臺(tái)服務(wù)器上都會(huì)安裝處理請(qǐng)求的應(yīng)用——web server顷扩。常見的web server產(chǎn)品有 apache、nginx慰毅、IIS等隘截。
web server擔(dān)任管控的角色,對(duì)于不同用戶發(fā)送的請(qǐng)求汹胃,會(huì)結(jié)合配置文件婶芭,把不同請(qǐng)求委托給服務(wù)器上處理相應(yīng)請(qǐng)求的程序進(jìn)行處理,然后返回后臺(tái)程序處理產(chǎn)生的結(jié)果作為響應(yīng)着饥。
http 響應(yīng)報(bào)文
響應(yīng)報(bào)文由響應(yīng)行犀农、響應(yīng)頭部、響應(yīng)主體三個(gè)部分組成宰掉。如下圖所示:
(1) 響應(yīng)行包含:協(xié)議版本井赌,狀態(tài)碼,狀態(tài)碼描述
狀態(tài)碼規(guī)則如下:
1xx:指示信息--表示請(qǐng)求已接收贵扰,繼續(xù)處理仇穗。
2xx:成功--表示請(qǐng)求已被成功接收、理解戚绕、接受纹坐。
3xx:重定向--要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作。
4xx:客戶端錯(cuò)誤--請(qǐng)求有語法錯(cuò)誤或請(qǐng)求無法實(shí)現(xiàn)舞丛。
5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求耘子。
(2) 響應(yīng)頭部包含響應(yīng)報(bào)文的附加信息果漾,由 名/值 對(duì)組成
(3) 響應(yīng)主體包含回車符、換行符和響應(yīng)返回?cái)?shù)據(jù)谷誓,并不是所有響應(yīng)報(bào)文都有響應(yīng)數(shù)據(jù)
瀏覽器解析渲染頁面
瀏覽器拿到響應(yīng)文本HTML后绒障,開始渲染頁面。
瀏覽器解析渲染頁面分為一下五個(gè)步驟:
- 根據(jù)HTML解析出DOM樹
- 根據(jù)CSS解析生成CSS規(guī)則樹
- 結(jié)合DOM樹和CSS規(guī)則樹捍歪,生成渲染樹
- 根據(jù)渲染樹計(jì)算每一個(gè)節(jié)點(diǎn)的信息
- 根據(jù)計(jì)算好的信息繪制頁面
斷開連接
當(dāng)數(shù)據(jù)傳送完畢户辱,需要斷開tcp連接,此時(shí)發(fā)起tcp四次揮手糙臼。
- 發(fā)起方向被動(dòng)方發(fā)送報(bào)文庐镐,F(xiàn)in、Ack变逃、Seq必逆,表示已經(jīng)沒有數(shù)據(jù)傳輸了。并進(jìn)入 FIN_WAIT_1 狀態(tài)揽乱。(第一次揮手:由瀏覽器發(fā)起的名眉,發(fā)送給服務(wù)器,我請(qǐng)求報(bào)文發(fā)送完了凰棉,你準(zhǔn)備關(guān)閉吧)
- 被動(dòng)方發(fā)送報(bào)文璧针,Ack、Seq渊啰,表示同意關(guān)閉請(qǐng)求探橱。此時(shí)主機(jī)發(fā)起方進(jìn)入 FIN_WAIT_2 狀態(tài)。(第二次揮手:由服務(wù)器發(fā)起的绘证,告訴瀏覽器隧膏,我請(qǐng)求報(bào)文接受完了,我準(zhǔn)備關(guān)閉了嚷那,你也準(zhǔn)備吧)
- 被動(dòng)方向發(fā)起方發(fā)送報(bào)文段胞枕,F(xiàn)in、Ack魏宽、Seq腐泻,請(qǐng)求關(guān)閉連接。并進(jìn)入 LAST_ACK 狀態(tài)队询。(第三次揮手:由服務(wù)器發(fā)起派桩,告訴瀏覽器,我響應(yīng)報(bào)文發(fā)送完了蚌斩,你準(zhǔn)備關(guān)閉吧)
- 發(fā)起方向被動(dòng)方發(fā)送報(bào)文段铆惑,Ack、Seq。然后進(jìn)入等待 TIME_WAIT 狀態(tài)员魏。被動(dòng)方收到發(fā)起方的報(bào)文段以后關(guān)閉連接丑蛤。發(fā)起方等待一定時(shí)間未收到回復(fù),則正常關(guān)閉撕阎。(第四次揮手:由瀏覽器發(fā)起受裹,告訴服務(wù)器,我響應(yīng)報(bào)文接受完了虏束,我準(zhǔn)備關(guān)閉了棉饶,你也準(zhǔn)備吧)
為什么建立連接是三次握手,而關(guān)閉連接卻是四次揮手呢魄眉?
這是因?yàn)榉?wù)端在LISTEN狀態(tài)下,收到建立連接請(qǐng)求的SYN報(bào)文后闷袒,把ACK和SYN放在一個(gè)報(bào)文里發(fā)送給客戶端坑律。而關(guān)閉連接時(shí),當(dāng)收到對(duì)方的FIN報(bào)文時(shí)囊骤,僅僅表示對(duì)方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)晃择,己方也未必全部數(shù)據(jù)都發(fā)送給對(duì)方了,所以己方可以立即關(guān)閉連接也物,也可以發(fā)送一些數(shù)據(jù)給對(duì)方后宫屠,再發(fā)送FIN報(bào)文給對(duì)方來表示同意現(xiàn)在關(guān)閉連接,因此滑蚯,己方ACK和FIN一般都會(huì)分開發(fā)送浪蹂。