我們知道目前很多應用系統中的內容傳輸協議採用的HTTP協議,因此不管你是前端人員、後端人員、運維人員,甚至是管理人員,都需要掌握HTTP知識!!
HTTP發展歷史
- HTTP/0.9
該版本只有一個命令GET;沒有HEADER等描述資料的資訊; 伺服器傳送完畢,就關閉TCP連線。
- HTTP/1.0
該版本增加了很多命令;增加status code 和header;多字符集支援、多部分傳送、許可權、快取等。
HTTP/1.1
該版本增加了持久連線、Pipeline,增加host和其他一些命令。持久連線會在HTTP特性中介紹;如果沒有pipeline,那麼Web伺服器就需要序列處理請求,而有了pipeline,Web伺服器就並行處理請求;而增加host實現了一臺物理裝置可以執行多個web服務。
- HTTP/2.0
所有資料以二進位制傳輸,之前版本使用字串進行傳輸;同一個連線 裡面傳送多個請求不再需要按照順序來;頭資訊壓縮以及推送等提高效率的功能。
HTTP三次握手
為什麼要三次握手?因為網路是有可能延遲的,當客戶端沒有收到服務端的確認包,如果沒有第三次握手,那麼服務端不知道上次傳輸是不是被客戶端正常接收了,如果沒有接收,服務端的這個埠也是開啟的,這就比較浪費資源。
HTTP報文
HTTP報文分為請求報文和響應報文,請求報文和響應報文分為起始行、首部(header)和主體(body),請求報文的首部包括三部分,分別是HTTP方法、資源目錄和協議,而響應報文的首部包括協議版本、狀態碼和狀態嗎對應的意思,比如200狀態的意思是ok。需要注意的是:HTTP header和HTTP body之間以一行分隔。
- HTTP方法
HTTP方法定義對資源的操作,常用的有GET、POST等,這就就不詳細展開了。
- HTTP Code
HTTP Code用於定義伺服器對請求的處理結果,各個區間的code有不用的語義。1xx 表示資訊響應類,表示接收到請求並且繼續處理;2xx 表示成功;3xx 表示重定向;4xx 表示客戶端出錯;5xx 表示伺服器出錯。
HTTP特性
- 跨域請求
同源策略,也就是說當兩個請求的URL的協議、host和埠都相同的情況下,我們才認為這兩個請求是同域的即同源,而只要協議、host和埠只要有一項是不同的,我們就認為是不同源的,即跨域,例如:
http://www.mukedada.com:80
http://www.mukedada.com:8080
上述兩個請求就是跨域請求。需要注意的是跨域請求不是說瀏覽器限制了發起跨站請求,瀏覽器只是將返回結果攔截下來,最好的例子就是CSRF跨站指令碼攻擊。如果我們想讓瀏覽器放行返回結果,則通過以下方法:
-
服務端設定Access-Control-Allow-Origin引數為允許,例如'Access-Control-Allow-Origin' : '*'
-
<link>
、<img>
和<script>
三標籤中的請求是允許跨域的,這也是JSONP的跨域做法。
- Cache Control
對於靜態資源,比如說image、js等,它們是不會經常方式變更的,而且它們的容量比較大,如果我們每次訪問都要從伺服器從獲取相應資料,那麼效能就會變得比較差,因此HTTP協議定義一些和快取相關的引數。
可快取性,表示在哪些地方可以快取,比如說客戶端瀏覽器、代理伺服器等,它有三個常用的引數:public、private、no-cache。public 表明響應可以被任何物件快取,包括髮送請求的客戶端瀏覽器、代理伺服器等等;private 表示響應只能被單個使用者快取,不能作為共享快取,即代理伺服器不能快取它;no-cache表明強制所有快取了該響應的快取使用者,在使用已儲存的快取之前,傳送帶驗證器的請求到源始伺服器。
到期,max-age=,設定快取儲存的最大週期,超過這個時間快取就被認為過期。s-maxage= 它的作用域僅在共享快取(比如各個代理)。max-stale= 表明客戶端願意接收一個已過期的資源。
驗證,must-revalidate,快取必須在使用之前驗證舊資源的狀態,並且不可使用過期資源。proxy-revalidate,與must-revalidate作用相同,但它僅適用於共享快取(例如代理),並被私有快取忽略。
其他。no-store,客戶端和代理伺服器不儲存任何快取,而是直接從伺服器獲取內容。no-transform:不得對資源進行轉換或轉變。Content-Encoding, Content-Range, Content-Type等HTTP頭不能由代理修改。例如,非透明代理可以對影像格式進行轉換,以便節省快取空間或者減少緩慢鏈路上的流量。 no-transform指令不允許這樣做。
- Cookie
服務端通過Set-Cookie將相關資料儲存到瀏覽器中,而這些相關資料就是Cookie,那麼,下次在同域的請求中就會帶上這些Cookie,Cookie是鍵值對,可以設定多個。Cookie中通過max-age和expires設定過期時間,Secure值在https的時候傳送,HttpOnly無法通過document.cookie訪問。具體可以參考Session 和 Cookie。
- 資源驗證
在Cache Control中我們介紹當設定no-cache引數時,表明每次請求都要到伺服器驗證,驗證結果表明可以讀取本地快取才可以從本地讀取快取。只有到資料發生修改時,我們才需要從服務端讀取最新資料,否則從本地讀取快取。此時,判斷資料是否發生修改就變得尤為重要,通常我們採用Last-Modfied和Etag兩個驗證頭來驗證資料是否發生修改。其中Last-Modifed 通常配合If-Modified-Since或者If-UnModified-Since使用,而Etag 通常配合If-Match或者If-Non-Match使用。為了幫助大家理解,我舉一個栗子。假設我們訪問mudedada.com返回頭資訊包含:
Last-Modified:888
Etag:123
下一次訪問mukedada.com的請求頭中就會包含:
If-Modified-Since:888
If-Non-Match:123
伺服器會比較請求頭中的Last-Modified、Etag 和伺服器中的對應值是否相同,如果不相同則重新獲取,否則從本地快取中獲取。
- 長連線
我們知道一個HTTP需要建立一個TCP連線,完成之後就關閉TCP連線,這個成本比較高(因為建立一個TCP連線需要通過三次握手),所以在HTTP/1.1開始支援長連線,請求頭標識是Connection:keep-alive。如下圖所示,同一個Connection ID表示同一個連線。需要注意的是同一個連線只能是同域請求。
- 資料協商
資料協商指的是客戶端向服務端傳送請求時,客戶端會宣告它希望服務端返回個格式是什麼?服務端根據客戶端的宣告來判斷返回什麼要的資料。其中客戶端通過Accept、Accept-Encoding等引數進行設定,而服務端通過Content-Type等引數進行設定。
客戶端相關引數:
-
Accept指定返回資料型別;
-
Accept-Encoding指定服務端的資料壓縮方式,目前服務端的壓縮演算法有gzip, deflate, br等;
-
Accept-Language指定返回資料的語言,例如 Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,其中q表示的是權重,也就是說瀏覽器更希望伺服器返回的是中文;
-
User-Agent表示瀏覽器的相關資訊,它能區分是移動端瀏覽器還是PC端瀏覽器,從而返回特定的頁面。
服務端相關引數:
-
Content-Type指的是服務端返回的資料型別;
-
Content-Encoding對應客戶端的Accept-Encoding,指的是資料壓縮方式;
-
Content-Language服務端語言。