優(yōu)化知識(shí)之快速掌握HTTP協(xié)議讓協(xié)議更友好
2019-05-14
HTTP 協(xié)議極其龐雜,它影響著瀏覽器、爬蟲、代理服務(wù)器、防火墻、CDN、Web 容器、微服務(wù)等諸多方面,自身的規(guī)范卻并不統(tǒng)一,所要面對(duì)的各類軟件的新舊版本也同時(shí)存在于網(wǎng)絡(luò)上。在這種情況下,如果對(duì) HTTP 沒有一個(gè)深入的理解,就很容易被各種各樣的網(wǎng)絡(luò)問(wèn)題難倒。
那么,如何才能快速掌握HTTP協(xié)議呢?
在我看來(lái),需要從以下四個(gè)方面入手:
工欲善其事,必先利其器,首先我們先要掌握好抓包及相關(guān)的工具,這樣在分析各種網(wǎng)絡(luò)協(xié)議時(shí)也就更加得心應(yīng)手。
先從架構(gòu)入手,搞清楚 HTTP 協(xié)議到底想解決什么問(wèn)題,面臨哪些非功能性的約束,又是怎樣一步步發(fā)展變遷至今的。
熟悉協(xié)議格式,對(duì)隧道或者正向代理下的 URI 格式、對(duì)多表述包體和不定長(zhǎng)包體的傳輸格式要了解,對(duì) DNS 的 QUESTION/ANSWER 也要了解。
掌握應(yīng)用場(chǎng)景,跨域訪問(wèn)與同源策略到底在糾結(jié)什么?代理服務(wù)器上的共享緩存如何精細(xì)化控制?
先給大家分享我整理的 HTTP 學(xué)習(xí)知識(shí)圖譜,你可以收藏起來(lái),時(shí)不時(shí)地拿出來(lái)對(duì)照:
(高清圖看這篇:http://note.youdao.com/noteshare?id=56e65085e89f449feb5804a887dbf058&sub=68510F5CB15E46C6BFA7021506A65330)
下面,我們來(lái)一一詳述這四個(gè)方面。
1、用好工具
學(xué)好HTTP協(xié)議,至少要用到下面4個(gè)工具:
1.1 Chrome Network抓包面板
這個(gè)工具有4個(gè)優(yōu)點(diǎn):
快速分析HTTP請(qǐng)求
便捷卸載TLS/SSL內(nèi)容
可協(xié)助分析頁(yè)面加載性能
方便分析websocket內(nèi)容
該工具包含5個(gè)面板,在過(guò)濾器的Filter輸入欄中還支持復(fù)雜的屬性過(guò)濾,在請(qǐng)求列表中可以看到請(qǐng)求的上下游,亦能看到每個(gè)請(qǐng)求的時(shí)間分布。
1.2 telnet
這個(gè)小工具主要用于構(gòu)造原始的應(yīng)用層協(xié)議,幫助我們理解HTTP實(shí)際在網(wǎng)絡(luò)中傳輸?shù)母袷绞鞘裁礃拥摹?/p>
1.3 curl
telnet有2個(gè)問(wèn)題:
1、太過(guò)繁瑣,每次要輸入完整的請(qǐng)求。實(shí)際我們可能只是想改一下方法或者某個(gè)HEADER頭部。
2、不支持HTTPS,不支持包體壓縮,導(dǎo)致無(wú)法向某些站點(diǎn)發(fā)起請(qǐng)求。
而curl完美解決了這些問(wèn)題。它也用于構(gòu)造定制化的HTTP請(qǐng)求,并可以分析HTTP響應(yīng)頭部或者包體。
1.4 Wireshark
這是學(xué)習(xí)完整Web協(xié)議棧的必備工具,我們可以在服務(wù)器端用tcpdump抓包后,在可視化的Wireshark上便捷分析。
Wireshark功能極為強(qiáng)大:
既支持BPF捕獲過(guò)濾器,也支持分析時(shí)的顯示過(guò)濾器;
通過(guò)流跟蹤或者會(huì)話圖標(biāo),我們可以輕松的以session會(huì)話為單位進(jìn)行分析;
通過(guò)可配置的著色規(guī)則,但以不同的色彩幫助我們輕松找出有問(wèn)題的報(bào)文;
通過(guò)報(bào)文的標(biāo)注及導(dǎo)出,以及文件的合并、時(shí)間的平移,可以輕松將多臺(tái)機(jī)器上的抓到的報(bào)文放在一起分析對(duì)比;
既可以通過(guò)Packet Detail中看到每層報(bào)文解析出的可讀值,也能在Packet Byte中看到二進(jìn)制流。
支持報(bào)文統(tǒng)計(jì),對(duì)大量HTTP報(bào)文的分析非常方便!
2、理解架構(gòu)
要理解HTTP的架構(gòu),需要從以下4個(gè)方面入手:
2.1 HTTP協(xié)議想解決什么問(wèn)題?
HTTP協(xié)議設(shè)計(jì)之初用于解決人與機(jī)器間的通訊,所謂“B/S架構(gòu)”中的瀏覽器是我們必須考慮進(jìn)的因素。
因此,HTTP協(xié)議需要傳輸超媒體數(shù)據(jù)(包括圖片、視頻等大粒度數(shù)據(jù))。
當(dāng)然,現(xiàn)在許多物聯(lián)網(wǎng)中的設(shè)備也在使用HTTP協(xié)議,所以,它也在解決機(jī)器與機(jī)器間的通訊。
當(dāng)然,網(wǎng)絡(luò)爬蟲也是HTTP協(xié)議要面對(duì)的問(wèn)題,robots.txt這樣的規(guī)范也應(yīng)運(yùn)而生。
2.2 HTTP協(xié)議面對(duì)哪些非功能性約束?
主要包括以下5個(gè)方面:
高可擴(kuò)展性,因?yàn)樗枰鎸?duì)全世界用戶群體以及數(shù)十年以上的壽命
低門檻,既有使用門檻也包括開發(fā)門檻,JavaApplet的式微與Javascript的如日中天就是極好的例證
分布式環(huán)境下的大粒度數(shù)據(jù)傳輸
internet下無(wú)法控制的負(fù)載以及種類版本繁多的組件
向前兼容,HTTP/1.1中的許多特性都需要照顧到還有僅支持HTTP/1.0的代理服務(wù)器在互聯(lián)網(wǎng)上運(yùn)行
2.3 遵循的架構(gòu)設(shè)計(jì)方案是怎樣的?
HTTP/1.1是完全遵循REST架構(gòu)設(shè)計(jì),而REST架構(gòu)主要包含以下4個(gè)子架構(gòu):
LCS:空間上分層的客戶端服務(wù)器,因此我們才有了隧道、代理、網(wǎng)關(guān)、CDN、負(fù)載均衡等產(chǎn)品;
CSS:無(wú)狀態(tài)的客戶端服務(wù)器,因此我們才有了Request/Response請(qǐng)求模式,才要求cookie頭部或者URL不能超過(guò)4K等。
COD:按需代碼,即將代碼從服務(wù)器移至客戶端再運(yùn)行,今天的前端生態(tài)都是基于此架構(gòu)下而生的Javascript衍伸的。
$:緩存,HTTP組件中無(wú)處沒有緩存,共享緩存、私有緩存,沒指明緩存時(shí)限還要預(yù)估一個(gè)緩存過(guò)期值。
2.4 HTTP協(xié)議特性有哪些?
首先,我們需要理解它在OSI概念模型的哪一層,它又是處在TCP/IP體系的什么位置。
其次,我們可以從上述架構(gòu)中推導(dǎo)出它的定義:一種無(wú)狀態(tài)的、應(yīng)用層的、以請(qǐng)求/應(yīng)答方式運(yùn)行的協(xié)議,它使用可擴(kuò)展的語(yǔ)義和自描述消息格式,與基于網(wǎng)絡(luò)的超文本信息系統(tǒng)靈活的互動(dòng)!
3、熟悉協(xié)議格式
學(xué)習(xí)HTTP協(xié)議格式時(shí),應(yīng)從以下3個(gè)方面入手:
3.1 擴(kuò)充巴科斯-瑙爾范式:ABNF元語(yǔ)言
元語(yǔ)言可用于描述協(xié)議格式,而ABNF就嚴(yán)謹(jǐn)定義了HTTP的格式。
ABNF并不復(fù)雜,只需要我們花10分鐘即可學(xué)會(huì),它包括操作符和核心規(guī)則2大部分,這里不再列出。
3.2 HTTP協(xié)議格式
掌握HTTP協(xié)議格式需要理清一個(gè)樹狀知識(shí)圖,參見本文末尾我整理的HTTP知識(shí)圖譜。
3.3 DNS協(xié)議格式
我們需要掌握3個(gè)方面的知識(shí):
DNS報(bào)文是基于UDP的,它的通用格式是固定的,需要理解各字段含義
Questions部分需要重點(diǎn)看QNAME域名是如何編碼的,以及QTYPE的含義
Answers部分字段更多,特別是對(duì)NAME及RDATA部分的偏移表示法要有所了解
4、掌握應(yīng)用場(chǎng)景
HTTP的應(yīng)用場(chǎng)景極其廣泛,下面我列出常見的9個(gè)場(chǎng)景,在協(xié)議格式中提到的各方法、響應(yīng)碼、頭部、包體編碼方式都與具體場(chǎng)景相關(guān)。
4.1 內(nèi)容如何協(xié)商
響應(yīng)式協(xié)商由于RFC規(guī)范不明少有使用,而主動(dòng)式協(xié)商關(guān)于語(yǔ)言、編碼、媒體類型等是我們?nèi)粘4蚪坏赖某R姺绞健?/p>
4.2 FORM表單如何提交
表單提交雖然有3種編碼方式,但最常用的還是boundary分隔的多表述共存于單一包體的方式,waf防火墻必須考慮如何應(yīng)用這種包體內(nèi)的SQL注入攻擊。
4.3 Range請(qǐng)求的使用
傳輸大文件所用到的斷點(diǎn)續(xù)傳和多線程下載,都需要使用Range規(guī)范,為防止多請(qǐng)求下載過(guò)程中服務(wù)器端更新的情況,還引入條件請(qǐng)求If-Range。
4.4 Cookie與Session的設(shè)計(jì)
Set-Cookie中有許多屬性,既有限制有效期的expires-av、max-age-av,也有限制使用范圍的domain-av、path-av,還有限制協(xié)議的secure-av或是限制使用對(duì)象的httponly-av。
這種種限制都在針對(duì)瀏覽器使用cookie是否安全,而同時(shí)為了便利性瀏覽器也支持第三方cookie,這更是為廠商搜集用戶信息提供了方便。
4.5 瀏覽器同源策略與跨域請(qǐng)求
同源策略是瀏覽器所做的限制,如果我們直接基于網(wǎng)絡(luò)庫(kù)處理響應(yīng)是不受此限制的。所以,這個(gè)同源策略的有效性非常依賴瀏覽器的實(shí)現(xiàn)。當(dāng)然,同源策略中不包含防范CSRF攻擊,服務(wù)器通?;趖oken策略解決CSRF攻擊。
安全與便利是必須權(quán)衡取舍的,為了增加便利性,必須允許AJAX的跨域請(qǐng)求,于是CORS便誕生了。
4.6 條件請(qǐng)求
條件請(qǐng)求不只可應(yīng)對(duì)多線程下載時(shí)的資源中途變量,也可針對(duì)多人協(xié)作的wiki系統(tǒng)生效,同時(shí)也能用于緩存更新。實(shí)際在Restful API設(shè)計(jì)中它大有發(fā)揮余地。
4.7 共享緩存與私有緩存
當(dāng)下的互聯(lián)網(wǎng)上緩存無(wú)處不在,即使服務(wù)器上沒有配置某些資源可以緩存,瀏覽器也在想盡辦法預(yù)估出一段時(shí)間緩存資源。因?yàn)?,緩存能夠極大的提升用戶體驗(yàn)、降低網(wǎng)絡(luò)負(fù)載!能夠控制緩存的HTTP頭部非常多,它不只控制緩存的有效期,也在控制緩存依據(jù)的關(guān)鍵字。
4.8 重定向的應(yīng)用
關(guān)于重定向我們需要從2個(gè)維度4個(gè)象限去理解:可更改方法 | 不可更改方法、可緩存|不可緩存
這便引出了301、302、303、307、308這5種不同的響應(yīng)狀態(tài)碼。
4.9 網(wǎng)絡(luò)爬蟲
爬蟲無(wú)處不在,遠(yuǎn)不只久遠(yuǎn)的搜索引擎爬蟲,當(dāng)下在出行(例如12306火車票或者亞航)、電商、社交(新浪微博)等都廣受爬蟲騷擾,爬蟲不只爬取信息,還模擬人類制造行為,例如許多搶票機(jī)、僵尸粉都如此。而另一方面,為了歡迎google/baidu的爬蟲,又誕生了各種SEO策略及教程,還有許多利用PageRank漏洞提升關(guān)鍵詞排名的商家在以此盈利。所以,理解爬蟲的工作方式也是非常重要的。
當(dāng)然,HTTP應(yīng)用場(chǎng)景遠(yuǎn)不止這些,但徹底掌握這些場(chǎng)景將使我們完全理解HTTP協(xié)議中常見的方法、頭部、響應(yīng)碼等等。
HTTP 協(xié)議是 Web 協(xié)議里非常重的一塊,作為程序員,無(wú)論你是前后端工程師,還是運(yùn)維測(cè)試,如果 想面試更高的職位,或者要站在更高的角度去理解技術(shù)業(yè)務(wù)架構(gòu),并能在問(wèn)題出現(xiàn)時(shí)快速、高效地解決問(wèn)題,Web 協(xié)議一定是你繞不過(guò)去的一道坎。 熟練掌握各種常用 Web 協(xié)議,可以幫你在工作中輕松應(yīng)對(duì)各種網(wǎng)絡(luò)難題。