通過閱讀該文章,你可以學到
- HTTP的傳輸原理
- HTTP的首部
- HTTPS的原理
HTTP的傳輸原理
HTTP想要傳送一條報文的時候,需要經過以下兩個步驟:
- TCP三次握手建立起連線管道,HTTP報文會以流的形式通過該管道按順序傳輸;
- TCP會將這些資料分別切割成資料塊,並且封裝在IP分組中,通過IP去傳輸;
使用TCP作為傳輸層:
- 傳輸可靠
- 有序
一個典型的HTTP請求過程如下圖所示:
HTTP協議首部
標準的HTTP協議共有GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE
。
GET
- 無副作用
- 可被快取
- 請求引數附帶在query中
POST
- 有副作用
- 不可被快取
- 請求引數在body中
HEAD
- 只會傳輸HTTP首部
OPTIONS
- 嗅探請求,用於判斷伺服器支援的方法
從字面上理解GET
、POST
,一個是獲取,一個是傳送,所以一般情況下我們在想讀取一個伺服器資源的時候我們會用GET
請求,當需要修改伺服器資料的時候,用POST
提交操作。
我們來看一個典型的GET
協議,
我們來看裡面幾個重要欄位:
Connection
在http1.0中一個http在傳輸完成之後就會斷開tcp連結,受到tcp慢啟動的特點,每次建立http都會消耗大量的時間,所以各個瀏覽器定義了一個不標準的協議叫keep-alive,當然在http1.1中已經預設開啟keep-alive,標識該請求在結束之後不會被斷開,也就是下一個請求可以不用進行DNS查詢,TCP三次握手,直接利用上一個通道進行傳輸。
上面兩張圖是我抓的天貓的兩個介面請求,可以看到,在第二個請求比第一個請求中少了DNS Lookup、Initial connection與SSL的過程,提升了差不多100ms左右的時間,效能提升非常明顯。
值得注意的是,因為keep-alive會複用一個tcp通道進行資料傳輸,怎樣知道一個資料傳輸完成了呢,這就必須用到Content-length,通過該屬性客戶端可以知道一個資源在什麼時候結束。
Cache-Control
上面的keep-alive對請求中的鏈路做了優化,在瀏覽器還有一個非常重要的欄位,Cache-control,該訊息頭被用於在http 請求和響應中通過指定指令來實現快取機制。
在response中伺服器可以通過max-age=x指定該資源的過期時間,標識在x秒之後同樣的請求直接走客戶端快取邏輯。
當然客戶端可以通過加入cache-control:no-cache
去強制強求伺服器資源。
上圖是瀏覽器的一些操作對快取的影響,實際原理就是強制修改request頭去影響快取,具體每個瀏覽器實現不一樣,這裡給出的是chrome瀏覽器的操作影響。
協商快取
當客戶端的cache-control過期了怎麼辦,是否必須向伺服器請求資源呢?
HTTP的設計者們當然沒有那麼傻,這個時候就要用到協商快取了。
Last-Modified
在服務端第一次返回資源的時候,如果帶上一個last-modified引數,也就是告知客戶端,這個資源在這個時間我更新過了,下次你記得給我帶過來,我驗證一下在這個時間之後是否有被更新過,如果沒有,那就返回304,你客戶端直接取本地快取即可,如果有更新,那會返回200,並且附上最新的last-modified值。
Etag
用Last-Modified有個問題,比如說我在一秒鐘更新了多次資源,那這個資源只要第一次被快取了,1秒鐘更新再多次請求的時候還是會返回304。另外有些檔案會被定時touch,這個時候檔案內容可能沒有變化,但是也會返回200。針對以上問題,出現了Etag,在第一次Response的時候,服務端會返回一個Etag,一般Etag是根據檔案雜湊計算出來的,所以只要檔案內容沒變,該Etag也唯一,這樣客戶端下次請求的時候帶上上次伺服器返回的Etag給伺服器校驗,如果兩次一樣,伺服器就會返回304。
encoding
客戶端通過Accept-Encoding欄位告知伺服器支援哪些壓縮演算法,伺服器收到後會選出一個最優演算法對資料進行壓縮,然後通過Content-Encoding返回給客戶端,告知客戶端去呼叫相關的演算法進行解壓。
cookie
使用者狀態追蹤器,一般在瀏覽一個網站的時候,該網站都會通過set-cookie植入一個sessionId在我們的cookie中來標識使用者身份。因為cookie會自動附帶在同域或者子域的請求上,通過cookie,廣告聯盟可以在任何站點嵌入一個iframe頁,植入廣告,這就是為什麼我們在上網的時候經常看到在某度、某東搜尋的資訊,當然我們可以開啟瀏覽器的隱私模式來避免資訊被盜取與濫用。
HTTPS
為什麼要進行升級HTTPS?
在網際網路出現之前,如果遠在天邊的兩個人想要聯絡只能通過寫信。讓我們看一下在中國的A要寄一封信給美國的B要經過哪些步驟。
A->中國郵局->郵遞員A.....->郵遞員Z->美國郵局->B
可以看到中間經過了很多鏈路,在每個環節都可以被任意偷窺甚至篡改,那麼信件到了B很可能就不是A的信了。
同樣在HTTP傳輸的過程中,我們可以把運營商類比為郵局,路由類比為郵遞員,因為HTTP在網路上是明文傳輸,可以被任何偷窺修改,典型的運營商劫持就是通過這種手段去操作的。
為了偷窺的問題,A跟B事先約定了一個辦法,A給了B一個密碼本,每個單詞字母都用對應的密碼錶示,每次A按照密碼本寫信,B收到後再通過密碼本解密,這樣在傳輸的過程中只要保證密碼本不落入他人手裡,其他人就沒法看得懂這封信了,這就是對稱加密。這樣看起來不錯,但是有個非常嚴重的問題,A的密碼本怎麼給到B,如果還是通過郵寄的方式,這樣密碼本被copy了,後面的所有的加密也是白瞎。
為了解決這種問題,B放出了一個公開的密碼本,說所有跟我通訊的人都按照這個密碼本的方式去加密,但是因為不是一一對映的關係,所以A加完密後連A自己都無法解密,但是B自己有金鑰,通過該金鑰可以解密信件。
這樣看起來解決了被偷窺的問題了,但是有一天B收到了一峰信件,發現用自己的金鑰解密後看不懂信件的內容,跟A溝通後,發現信件被篡改了。
為了解決這個問題,A每次寄信的時候都會按上自己的指紋,B收到信後首先確定這個指紋是不是A,然後再決定是否去解密,這樣問題差不多就解決了。
HTTPS的原理
HTTPS缺點
- 慢,初次建立SSL連線,演算法複雜,消耗資源
- 貴,需要每年交一定的費用給證書頒發機構