三次握手和四次揮手
請(qǐng)求類型
SYN :請(qǐng)求建立
ACK :請(qǐng)求確認(rèn)
FIN :請(qǐng)求關(guān)閉
三次握手
- 1:客戶端發(fā)送一個(gè) SYN
- 2:服務(wù)端收到 SYN,返回一個(gè) SYN 和 ACK
- 3:客戶端返回一個(gè) ACK,此時(shí)建立連接。
為什么三次?
我的理解是,防止客戶端發(fā)送 SYN 后,過(guò)來(lái)很久時(shí)間服務(wù)端才收到,若此時(shí)客戶端不再需要建立連接,服務(wù)端建立連接會(huì)導(dǎo)致資源的浪費(fèi),所以需要再次返回一個(gè) SYN 和 ACK。
四次揮手
- 1:客戶端發(fā)送 FIN
- 2:服務(wù)端收到 FIN,返回 ACK
- 3:服務(wù)端關(guān)閉連接后返回 FIN
- 4:客戶端收到 FIN,返回 ACK
為什么 2、3 不一起返回?
我的理解是,當(dāng)服務(wù)端收到 FIN 后,會(huì)關(guān)閉連接,但關(guān)閉是一個(gè)異步的操作,需要時(shí)間去關(guān)閉,這個(gè)時(shí)間不確定,如果花了很長(zhǎng)時(shí)間才關(guān)閉,客戶端就會(huì)等很久,但客戶端其實(shí)不需要關(guān)心你那邊有沒(méi)有關(guān)閉,所以服務(wù)端會(huì)先返回一個(gè) ACK,告訴客戶端我知道了,正在關(guān),客戶端收到后可以去先執(zhí)行其他事務(wù),而服務(wù)端等到關(guān)閉后,再發(fā)送一個(gè) FIN,此時(shí)客戶端收到后,會(huì)返回一個(gè) ACK 表示明白。
HTTP 狀態(tài)碼
100、200:狀態(tài)
- 100:消息處理,繼續(xù)請(qǐng)求
- 200:成功請(qǐng)求
300+ 資源更改
比如鏈接重定向、緩存已修改,常見(jiàn)為:
- 300:重定向多個(gè)鏈接,服務(wù)器根據(jù)用戶請(qǐng)求來(lái)進(jìn)行跳轉(zhuǎn)
- 301:永久重定向
- 302:臨時(shí)重定向
- 303:其他 URL 位置可以找到這個(gè)請(qǐng)求
- 304:文件未修改,可以繼續(xù)使用(HTTP 緩存使用的),只返回 header 所以更快
400+ 請(qǐng)求錯(cuò)誤
常見(jiàn)為:
- 400:無(wú)法理解的請(qǐng)求
- 401:請(qǐng)求頁(yè)面需要賬號(hào)和密碼,也就是訪問(wèn)受限,和登陸接口 token 過(guò)期一樣
- 403:頁(yè)面請(qǐng)求被禁止
- 404:頁(yè)面不存在
500+ 服務(wù)端錯(cuò)誤
常見(jiàn)為:
- 500:服務(wù)器發(fā)生了一個(gè)不可預(yù)知的錯(cuò)誤,通常就是沒(méi)有進(jìn)行錯(cuò)誤處理,導(dǎo)致代碼出現(xiàn)問(wèn)題。。
- 501:服務(wù)器不支持所請(qǐng)求的功能
- 502:錯(cuò)誤網(wǎng)關(guān),服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到無(wú)效響應(yīng),比如這個(gè)請(qǐng)求的代碼去請(qǐng)求了另一個(gè) api,這個(gè) api 掛掉了。
- 503:服務(wù)器暫時(shí)無(wú)法使用,超載或宕機(jī)。。
- 504:網(wǎng)關(guān)超時(shí),服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到無(wú)效響應(yīng),比如這個(gè)請(qǐng)求的代碼去請(qǐng)求了另一個(gè) api,這個(gè) api 超時(shí)了。
HTTP 的持續(xù)連接
- HTTP1.0:輪詢請(qǐng)求,持續(xù)請(qǐng)求保持不斷開(kāi),比較消耗資源
- HTTP1.1:在請(qǐng)求頭帶上 Connection: keep-alive,可以保持連接
HTTP 緩存
首先瀏覽器的緩存可以理解為在瀏覽器內(nèi)部有一個(gè)小型的緩存數(shù)據(jù)庫(kù),某鍵對(duì)應(yīng)某文件。
而頁(yè)面在加載的時(shí)候,會(huì)根據(jù)要求把文件放入緩存,也會(huì)根據(jù)需求去讀取使用,具體分為兩種類型:
- 強(qiáng)制緩存
- 協(xié)商緩存
強(qiáng)制緩存
假設(shè)文件為強(qiáng)制緩存,流程如下:
- 1:讀取緩存數(shù)據(jù)庫(kù)的數(shù)據(jù),有數(shù)據(jù)進(jìn)入下一步,無(wú)數(shù)據(jù)進(jìn)入第 3 步。
- 2:檢查數(shù)據(jù)是否到期,到期進(jìn)入下一步,未到期則使用。
- 3:請(qǐng)求數(shù)據(jù)使用并緩存到本地緩存數(shù)據(jù)庫(kù)中。
是否強(qiáng)制緩存根據(jù)相應(yīng)頭上的一個(gè)字段判斷,根據(jù) HTTP 的版本不同,有不同為不同的字段:
HTTP1.0:Expires 字段代碼其到期時(shí)間。
HTTP1.1:Cache-Control 字段控制,其可選值如下:
- private:前端保存
- public:前后端都保存
- max-age:緩存的內(nèi)容將在 n 秒后失效
- no-store:有內(nèi)容都不會(huì)緩存
- no-cache:需要使用對(duì)比緩存來(lái)驗(yàn)證緩存數(shù)據(jù)
協(xié)商緩存
假設(shè)文件為協(xié)商緩存,流程如下:
- 1:讀取緩存數(shù)據(jù)庫(kù)的數(shù)據(jù),有數(shù)據(jù)進(jìn)入下一步,無(wú)數(shù)據(jù)進(jìn)入第 3 步。
- 2:發(fā)送請(qǐng)求,確認(rèn)數(shù)據(jù)是否修改,修改則進(jìn)入下一步,未修改則使用。
- 3:請(qǐng)求數(shù)據(jù)使用并緩存到本地緩存數(shù)據(jù)庫(kù)中。
分開(kāi)說(shuō)一下 HTTP1.0 和 HTTP2.0 的區(qū)別。
HTTP1.0
在文件的第一次請(qǐng)求時(shí),響應(yīng)頭會(huì)返回一個(gè)字段:Last-Modified,代表此資源的最后修改時(shí)間,瀏覽器保留此值。
在后面的請(qǐng)求中,請(qǐng)求頭中會(huì)存在 If-Modified-Since 的字段,值為第一次的 Last-Modified 的值。
服務(wù)器以此進(jìn)行比較,判斷最后返回 200 或 304,若是 200 的話,取響應(yīng)頭的 Last-Modified 值更新本地保存的。
PS:這樣比較的話,如果文件僅僅是 ctrl + s 一下,也會(huì)進(jìn)行更新。
HTTP1.1
在文件的第一次請(qǐng)求時(shí),響應(yīng)頭會(huì)返回一個(gè)字段:Etag,代表服務(wù)器以此資源而生成一個(gè) id 標(biāo)志,瀏覽器保留此值。
在后面的請(qǐng)求中,請(qǐng)求頭中會(huì)存在 If-None-Match 的字段,值為第一次的 Etag 的值。
服務(wù)器以此進(jìn)行比較,判斷最后返回 200 或 304,若是 200 的話,取響應(yīng)頭的 Etag 值更新本地保存的。
PS:這樣比較的話,文件內(nèi)容不變是不會(huì)更新的。