不詩(shī)意的女程序媛不是好廚師~
轉(zhuǎn)載請(qǐng)注明出處,F(xiàn)rom李詩(shī)雨---https://blog.csdn.net/cjm2484836553/article/details/104136511
1. Http的協(xié)議簡(jiǎn)介
1.1什么是Http请梢?
HTTP即:Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫(xiě)。
它是用于從萬(wàn)維網(wǎng)(WWW:World
Wide Web )服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議最楷。
HTTP是一個(gè)基于TCP/IP通信協(xié)議來(lái)傳遞數(shù)據(jù)(HTML 文件, 圖片文件, 查詢(xún)結(jié)果等)揽咕。
1.2 Http的三個(gè)特點(diǎn)
HTTP三點(diǎn)注意事項(xiàng):
- HTTP是無(wú)連接:無(wú)連接的含義是限制每次連接只處理一個(gè)請(qǐng)求腹泌。服務(wù)器處理完客戶(hù)的請(qǐng)求,并收到客戶(hù)的應(yīng)答后换淆,即斷開(kāi)連接哗总。采用這種方式可以節(jié)省傳輸時(shí)間。
- HTTP是媒體獨(dú)立的:這意味著倍试,只要客戶(hù)端和服務(wù)器知道如何處理的數(shù)據(jù)內(nèi)容讯屈,任何類(lèi)型的數(shù)據(jù)都可以通過(guò)HTTP發(fā)送∠叵埃客戶(hù)端以及服務(wù)器指定使用適合的MIME-type內(nèi)容類(lèi)型涮母。
- HTTP是無(wú)狀態(tài):HTTP協(xié)議是無(wú)狀態(tài)協(xié)議。無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒(méi)有記憶能力躁愿。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息叛本,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大彤钟。另一方面来候,在服務(wù)器不需要先前信息時(shí)它的應(yīng)答就較快。
1.3 Http的歷史
- 1991年 Http/0.9 只有Get命令逸雹,只能獲取文本信息营搅。
- 1996年 Http/1.0 標(biāo)準(zhǔn)版本 豐富了命令,可以發(fā)送任何格式內(nèi)容(文字梆砸、圖像转质、視頻、二進(jìn)制文件等)帖世。
- 1997年Http/1.1 一直比較流行的版本 引入持久連接休蟹,TCP默認(rèn)不關(guān)閉,可被多個(gè)請(qǐng)求復(fù)用。
- 2015年Http/2.0 采用二進(jìn)制格式而非文本格式赂弓,允許服務(wù)器主動(dòng)推送绑榴。
2.Http的報(bào)文格式
2.1 Http請(qǐng)求報(bào)文
一個(gè)HTTP請(qǐng)求報(bào)文由四個(gè)部分組成:請(qǐng)求行、請(qǐng)求頭部盈魁、空行彭沼、請(qǐng)求數(shù)據(jù)。
請(qǐng)求行由請(qǐng)求方法字段备埃、URL字段和HTTP協(xié)議版本字段3個(gè)字段組成,它們用空格分隔褐奴。
-
請(qǐng)求頭部:Http客戶(hù)程序(例如瀏覽器)按脚,向服務(wù)器發(fā)送請(qǐng)求的時(shí)候必須指明請(qǐng)求類(lèi)型(一般是GET或者 POST)。
如有必要敦冬,客戶(hù)程序還可以選擇發(fā)送其他的請(qǐng)求頭辅搬。大多數(shù)請(qǐng)求頭并不是必需的,但
Content-Length
除外脖旱。對(duì)于
POST
請(qǐng)求來(lái)說(shuō)Content-Length
必須出現(xiàn)堪遂。還有下文說(shuō)的緩存機(jī)制的相關(guān)信息也放在請(qǐng)求頭中。
空行: 它的作用是通過(guò)一個(gè)空行萌庆,告訴服務(wù)器請(qǐng)求頭部到此為止溶褪。
-
請(qǐng)求數(shù)據(jù): 若方法字段是GET,則此項(xiàng)為空践险,沒(méi)有數(shù)據(jù)
若方法字段是POST,則通常來(lái)說(shuō)此處放置的就是要提交的數(shù)據(jù)
比如要使用POST方法提交一個(gè)表單猿妈,其中有user字段中數(shù)據(jù)為“admin”, password字段為123abc,那么這里的請(qǐng)求數(shù)據(jù)就是 user=admin&password=123abc巍虫,使用&來(lái)連接各個(gè)字段彭则。
概括點(diǎn)來(lái)說(shuō),HTTP請(qǐng)求報(bào)文格式如下:
2.2 Http響應(yīng)報(bào)文
同樣的占遥,HTTP響應(yīng)報(bào)文也由四部分組成:響應(yīng)行俯抖、響應(yīng)頭、空行瓦胎、響應(yīng)體
- 響應(yīng)行: 一般由協(xié)議版本芬萍、狀態(tài)碼及其描述組成 如 HTTP/1.1 200 OK
- 響應(yīng)頭: 用于描述服務(wù)器的基本信息,以及數(shù)據(jù)的描述凛捏,服務(wù)器通過(guò)這些數(shù)據(jù)的描述信息担忧,可以通知客戶(hù)端如何處理等一會(huì)兒它回送的數(shù)據(jù)。如下文要說(shuō)的一些緩存信息坯癣。
- 空行: 它的作用是通過(guò)一個(gè)空行瓶盛,告訴服務(wù)器請(qǐng)求頭部到此為止。
- 響應(yīng)體: 就是響應(yīng)的消息體,如果是純數(shù)據(jù)就是返回純數(shù)據(jù)惩猫,如果請(qǐng)求的是HTML頁(yè)面芝硬,那么返回的就是HTML代碼,如果是js就是JS代碼轧房,如此之類(lèi)拌阴。
3.Http請(qǐng)求的傳輸過(guò)程
像穿衣服一樣,早上起床是:由里向外的一層一層穿上奶镶;
睡覺(jué)時(shí)迟赃,再?gòu)耐獾嚼锏囊粚右粚用撓隆?/p>
或者說(shuō)像洋蔥~~~總之你理解就好。
4.一次完整Http請(qǐng)求的過(guò)程(面試點(diǎn)▲▲▲)
面試時(shí)經(jīng)常會(huì)被問(wèn)到厂镇,“請(qǐng)說(shuō)一下一次完整的Http請(qǐng)求過(guò)程是怎樣的”纤壁?
那么到底是怎樣的呢?請(qǐng)看下文:
-
① 域名解析
這個(gè)是由于捺信,socket只認(rèn)識(shí)ip地址酌媒,不認(rèn)識(shí)域名,所以要先進(jìn)行域名解析迄靠。
-
② 建立TCP連接
HTTP 是比 TCP 更高層次的應(yīng)用層協(xié)議秒咨,根據(jù)規(guī)則,只有低層協(xié)議建立之后才能進(jìn)行更高層協(xié)議的連接掌挚,因此雨席,首先要建立 TCP 連接。TCP通過(guò)三次握手建立連接疫诽,在前一篇文章中說(shuō)過(guò)舅世。
-
③ 瀏覽器向服務(wù)器發(fā)送請(qǐng)求命令
一旦建立了 TCP 連接,Web 瀏覽器就會(huì)向 Web 服務(wù)器發(fā)送請(qǐng)求命令奇徒。
例如:GET/hello/index.jsp HTTP/1.1雏亚。瀏覽器發(fā)送其請(qǐng)求命令之后,還要以頭信息的形式向Web服務(wù)器發(fā)送一些別的信息(例:Accept ,User-Agent 等)摩钙,之后瀏覽器發(fā)送了一空白行來(lái)通知服務(wù)器罢低,它已經(jīng)結(jié)束了該頭信息的發(fā)送。
-
④ Web服務(wù)器應(yīng)答
客戶(hù)端向服務(wù)器發(fā)出請(qǐng)求后胖笛,服務(wù)器會(huì)進(jìn)行應(yīng)答网持。
-
⑤ Web服務(wù)器關(guān)閉TCP連接
一般情況下,一旦 Web 服務(wù)器向?yàn)g覽器發(fā)送了請(qǐng)求的數(shù)據(jù)长踊,它就要關(guān)閉 TCP 連接功舀。
但是如果瀏覽器或者服務(wù)器在其頭信息加入了這行代碼:Connection:keep-alive,TCP連接在發(fā)送后將仍然保持打開(kāi)狀態(tài)身弊,于是辟汰,瀏覽器可以繼續(xù)通過(guò)相同的連接發(fā)送請(qǐng)求列敲。保持連接節(jié)省了為每個(gè)請(qǐng)求建立新連接所需的時(shí)間,還節(jié)約了網(wǎng)絡(luò)帶寬帖汞。
-
⑥ 瀏覽器接受到服務(wù)器響應(yīng)的數(shù)據(jù)
瀏覽器接受服務(wù)器應(yīng)答回來(lái)的 html 代碼和css戴而,和js代碼再進(jìn)行頁(yè)面的渲染或者接受到應(yīng)答的文件進(jìn)行保存等操作。
概括一下流程就是:
瀏覽器發(fā)起請(qǐng)求 → 解析域名得到ip→進(jìn)行TCP連接 →瀏覽器發(fā)送HTTP請(qǐng)求和頭信息發(fā)送→服務(wù)器對(duì)瀏覽器進(jìn)行應(yīng)答翩蘸,響應(yīng)頭信息和瀏覽器所需的內(nèi)容→ 關(guān)閉TCP連接或保持→瀏覽器得到數(shù)據(jù)數(shù)據(jù)進(jìn)行操作
5.Http的緩存機(jī)制及原理(面試點(diǎn)▲▲▲)
關(guān)于緩存機(jī)制和原理這部分內(nèi)容所意,我看到了一篇寫(xiě)得極好的文章:https://www.cnblogs.com/chenqf/p/6386163.html ,所以這一部分的內(nèi)容我就直接轉(zhuǎn)載了。
5.1 先來(lái)大概了解一下兩種緩存規(guī)則
HTTP緩存有多種規(guī)則催首,根據(jù)是否需要重新向服務(wù)器發(fā)起請(qǐng)求來(lái)分類(lèi)扶踊,我將其分為兩大類(lèi)(強(qiáng)制緩存,對(duì)比緩存)
下面我們通過(guò)時(shí)序圖的方式來(lái)學(xué)習(xí)兩種緩存規(guī)則:
為方便大家理解郎任,我們認(rèn)為瀏覽器存在一個(gè)緩存數(shù)據(jù)庫(kù),用于存儲(chǔ)緩存信息姻檀。
在客戶(hù)端第一次請(qǐng)求數(shù)據(jù)時(shí),此時(shí)緩存數(shù)據(jù)庫(kù)中沒(méi)有對(duì)應(yīng)的緩存數(shù)據(jù)涝滴,需要請(qǐng)求服務(wù)器,服務(wù)器返回后胶台,將數(shù)據(jù)存儲(chǔ)至緩存數(shù)據(jù)庫(kù)中歼疮。
然后,我們?cè)俜謩e來(lái)看看強(qiáng)制緩存和對(duì)比緩存的時(shí)序圖~
已存在緩存數(shù)據(jù)時(shí)诈唬,僅基于強(qiáng)制緩存韩脏,請(qǐng)求數(shù)據(jù)的流程如下:
已存在緩存數(shù)據(jù)時(shí),僅基于對(duì)比緩存铸磅,請(qǐng)求數(shù)據(jù)的流程如下:
我們可以看到兩類(lèi)緩存規(guī)則的不同赡矢,強(qiáng)制緩存如果生效,不需要再和服務(wù)器發(fā)生交互阅仔,而對(duì)比緩存不管是否生效吹散,都需要與服務(wù)端發(fā)生交互。
兩類(lèi)緩存規(guī)則可以同時(shí)存在八酒,強(qiáng)制緩存優(yōu)先級(jí)高于對(duì)比緩存空民,也就是說(shuō),當(dāng)執(zhí)行強(qiáng)制緩存的規(guī)則時(shí)羞迷,如果緩存生效界轩,直接使用緩存,不再執(zhí)行對(duì)比緩存規(guī)則衔瓮。
問(wèn)題: 基于對(duì)比緩存的流程下浊猾,不管是否使用緩存,都需要向服務(wù)器發(fā)送請(qǐng)求热鞍,那么還用緩存干什么葫慎?
答案是: 服務(wù)端在進(jìn)行標(biāo)識(shí)比較后衔彻,只返回header部分,通過(guò)狀態(tài)碼通知客戶(hù)端使用緩存幅疼,不再需要將報(bào)文主體部分返回給客戶(hù)端米奸。所以,在對(duì)比緩存生效時(shí)爽篷,狀態(tài)碼為304悴晰,報(bào)文大小和請(qǐng)求時(shí)間都會(huì)大大減少。
5.2 強(qiáng)制緩存
從上文我們知道逐工,強(qiáng)制緩存铡溪,在緩存數(shù)據(jù)未失效的情況下,可以直接使用緩存數(shù)據(jù)泪喊,那么瀏覽器是如何判斷緩存數(shù)據(jù)是否失效呢棕硫?
我們知道,在沒(méi)有緩存數(shù)據(jù)的時(shí)候袒啼,瀏覽器向服務(wù)器請(qǐng)求數(shù)據(jù)時(shí)哈扮,服務(wù)器會(huì)將數(shù)據(jù)和緩存規(guī)則一并返回,緩存規(guī)則信息包含在響應(yīng)header中蚓再。
對(duì)于強(qiáng)制緩存來(lái)說(shuō)滑肉,響應(yīng)header中會(huì)有兩個(gè)字段來(lái)標(biāo)明失效規(guī)則 Expires/Cache-Control
使用chrome的開(kāi)發(fā)者工具,可以很明顯的看到對(duì)于強(qiáng)制緩存生效時(shí)摘仅,網(wǎng)絡(luò)請(qǐng)求的情況
Expires
Expires的值為服務(wù)端返回的到期時(shí)間靶庙,即下一次請(qǐng)求時(shí),請(qǐng)求時(shí)間小于服務(wù)端返回的到期時(shí)間娃属,直接使用緩存數(shù)據(jù)六荒。
不過(guò)Expires 是HTTP 1.0的東西,現(xiàn)在默認(rèn)瀏覽器均默認(rèn)使用HTTP 1.1矾端,所以它的作用基本忽略掏击。
另一個(gè)問(wèn)題是,到期時(shí)間是由服務(wù)端生成的秩铆,但是客戶(hù)端時(shí)間可能跟服務(wù)端時(shí)間有誤差铐料,這就會(huì)導(dǎo)致緩存命中的誤差。
所以HTTP 1.1 的版本豺旬,使用Cache-Control替代钠惩。
Cache-Control
Cache-Control 是最重要的規(guī)則。常見(jiàn)的取值有private族阅、public篓跛、no-cache、max-age坦刀,no-store愧沟,默認(rèn)為private蔬咬。
private: 客戶(hù)端可以緩存
public: 客戶(hù)端和代理服務(wù)器都可緩存(前端的同學(xué),可以認(rèn)為public和private是一樣的)
max-age=xxx: 緩存的內(nèi)容將在 xxx 秒后失效
no-cache: 需要使用對(duì)比緩存來(lái)驗(yàn)證緩存數(shù)據(jù)(后面介紹)
no-store: 所有內(nèi)容都不會(huì)緩存沐寺,強(qiáng)制緩存林艘,對(duì)比緩存都不會(huì)觸發(fā)(對(duì)于前端開(kāi)發(fā)來(lái)說(shuō),緩存越多越好混坞,so...基本上和它說(shuō)886)
5.3 對(duì)比緩存
對(duì)比緩存狐援,顧名思義,需要進(jìn)行比較判斷是否可以使用緩存究孕。
瀏覽器第一次請(qǐng)求數(shù)據(jù)時(shí)啥酱,服務(wù)器會(huì)將緩存標(biāo)識(shí)與數(shù)據(jù)一起返回給客戶(hù)端,客戶(hù)端將二者備份至緩存數(shù)據(jù)庫(kù)中厨诸。
再次請(qǐng)求數(shù)據(jù)時(shí)镶殷,客戶(hù)端將備份的緩存標(biāo)識(shí)發(fā)送給服務(wù)器,服務(wù)器根據(jù)緩存標(biāo)識(shí)進(jìn)行判斷微酬,判斷成功后绘趋,返回304狀態(tài)碼,通知客戶(hù)端比較成功颗管,可以使用緩存數(shù)據(jù)埋心。
第一次訪問(wèn)的截圖:
再次訪問(wèn)的截圖:
通過(guò)兩圖的對(duì)比,我們可以很清楚的發(fā)現(xiàn)忙上,在對(duì)比緩存生效時(shí),狀態(tài)碼為304闲坎,并且報(bào)文大小和請(qǐng)求時(shí)間大大減少疫粥。
原因是,服務(wù)端在進(jìn)行標(biāo)識(shí)比較后腰懂,只返回header部分梗逮,通過(guò)狀態(tài)碼通知客戶(hù)端使用緩存,不再需要將報(bào)文主體部分返回給客戶(hù)端绣溜。
對(duì)于對(duì)比緩存來(lái)說(shuō)慷彤,緩存標(biāo)識(shí)的傳遞是我們著重需要理解的,它在請(qǐng)求header和響應(yīng)header間進(jìn)行傳遞怖喻,
一共分為兩種標(biāo)識(shí)傳遞底哗,接下來(lái),我們分開(kāi)介紹锚沸。
Last-Modified / If-Modified-Since
Last-Modified:
服務(wù)器在響應(yīng)請(qǐng)求時(shí)跋选,告訴瀏覽器資源的最后修改時(shí)間。
If-Modified-Since:
再次請(qǐng)求服務(wù)器時(shí)哗蜈,通過(guò)此字段通知服務(wù)器上次請(qǐng)求時(shí)前标,服務(wù)器返回的資源最后修改時(shí)間坠韩。
服務(wù)器收到請(qǐng)求后發(fā)現(xiàn)有頭If-Modified-Since 則與被請(qǐng)求資源的最后修改時(shí)間進(jìn)行比對(duì)。
若資源的最后修改時(shí)間大于If-Modified-Since炼列,說(shuō)明資源又被改動(dòng)過(guò)只搁,則響應(yīng)整片資源內(nèi)容,返回狀態(tài)碼200俭尖;
若資源的最后修改時(shí)間小于或等于If-Modified-Since氢惋,說(shuō)明資源無(wú)新修改,則響應(yīng)HTTP 304目溉,告知瀏覽器繼續(xù)使用所保存的cache明肮。
Etag / If-None-Match
優(yōu)先級(jí)高于Last-Modified / If-Modified-Since
Etag:
服務(wù)器響應(yīng)請(qǐng)求時(shí),告訴瀏覽器當(dāng)前資源在服務(wù)器的唯一標(biāo)識(shí)(生成規(guī)則由服務(wù)器決定)缭付。
If-None-Match:
再次請(qǐng)求服務(wù)器時(shí)柿估,通過(guò)此字段通知服務(wù)器客戶(hù)段緩存數(shù)據(jù)的唯一標(biāo)識(shí)。
服務(wù)器收到請(qǐng)求后發(fā)現(xiàn)有頭If-None-Match 則與被請(qǐng)求資源的唯一標(biāo)識(shí)進(jìn)行比對(duì)陷猫,
不同秫舌,說(shuō)明資源又被改動(dòng)過(guò),則響應(yīng)整片資源內(nèi)容绣檬,返回狀態(tài)碼200足陨;
相同,說(shuō)明資源無(wú)新修改娇未,則響應(yīng)HTTP 304墨缘,告知瀏覽器繼續(xù)使用所保存的cache。
總結(jié)
對(duì)于強(qiáng)制緩存零抬,服務(wù)器通知瀏覽器一個(gè)緩存時(shí)間镊讼,在緩存時(shí)間內(nèi),下次請(qǐng)求平夜,直接用緩存蝶棋,不在時(shí)間內(nèi),執(zhí)行比較緩存策略忽妒。對(duì)于比較緩存玩裙,將緩存信息中的Etag和Last-Modified通過(guò)請(qǐng)求發(fā)送給服務(wù)器,由服務(wù)器校驗(yàn)段直,返回304狀態(tài)碼時(shí)吃溅,瀏覽器直接使用緩存。
瀏覽器第一次請(qǐng)求:
瀏覽器再次請(qǐng)求: