http基本概念
http是一個無狀態 ,無連線的基於TCP協議的單向應用層協議
一、無連線
無連線即每次連結只處理一個請求,請求和應答後就斷開連結
二、無狀態
http的每次請求都是獨立的,不相關的,協議對事物處理沒有記憶功能。 HTTP無狀態的特性嚴重阻礙了這些互動式應用程式的實現,畢竟互動是需要承前啟後的,簡單的購物車程式也要知道使用者到底在之前選擇了什麼商品。於是,兩種用於保持HTTP狀態的技術就應運而生了,一個是Cookie,而另一個則是Session。
HTTP請求報文
HTTP請求報文由3部分組成(報文行+報文頭+報文體):
常見的HTTP響應報文頭屬性
Cache-Control
響應輸出到客戶端後,服務端通過該報文頭屬告訴客戶端如何控制響應內容的快取。
常見的取值有private、public、no-cache、max-age,no-store,預設為private。
private: 客戶端可以快取
public: 客戶端和代理伺服器都可快取(前端的同學,可以認為public和private是一樣的)
max-age=xxx: 快取的內容將在 xxx 秒後失效
no-cache: 需要使用對比快取來驗證快取資料
no-store: 所有內容都不會快取
預設為private,快取時間為31536000秒(365天)也就是說,在365天內再次請求這條資料,都會直接獲取快取資料庫中的資料,直接使用。
ETag
一個代表響應服務端資源(如頁面)版本的報文頭屬性,如果某個服務端資源發生變化了,這個ETag就會相應發生變化。它是Cache-Control的有益補充,可以讓客戶端“更智慧”地處理什麼時候要從服務端取資源,什麼時候可以直接從快取中返回響應。
Location
我們在JSP中讓頁面Redirect到一個某個A頁面中,其實是讓客戶端再發一個請求到A頁面,這個需要Redirect到的A頁面的URL,其實就是通過響應報文頭的Location屬性告知客戶端的,如下的報文頭屬性,將使客戶端redirect到iteye的首頁中:
Location: www.iteye.com
Set-Cookie
服務端可以設定客戶端的Cookie,其原理就是通過這個響應報文頭屬性實現的:
Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
更多詳細見 (一個介紹http的地址)
http code
2XX 成功
200 OK,表示從客戶端發來的請求在伺服器端被正確處理
204 No content,表示請求成功,但響應報文不含實體的主體部分
205 Reset Content,表示請求成功,但響應報文不含實體的主體部分,但是與 204 響應不同在於要求請求方重置內容
206 Partial Content,進行範圍請求
3XX 重定向
301 moved permanently,永久性重定向,表示資源已被分配了新的 URL
302 found,臨時性重定向,表示資源臨時被分配了新的 URL
303 see other,表示資源存在著另一個 URL,應使用 GET 方法獲取資源
304 not modified,表示伺服器允許訪問資源,但因發生請求未滿足條件的情況(快取)
307 temporary redirect,臨時重定向,和302含義類似,但是期望客戶端保持請求方法不變向新的地址發出請求
4XX 客戶端錯誤
400 bad request,請求報文存在語法錯誤
401 unauthorized,表示傳送的請求需要有通過 HTTP 認證的認證資訊
403 forbidden,表示對請求資源的訪問被伺服器拒絕
404 not found,表示在伺服器上沒有找到請求的資源
5XX 伺服器錯誤
500 internal sever error,表示伺服器端在執行請求時發生了錯誤
501 Not Implemented,表示伺服器不支援當前請求所需要的某個功能
503 service unavailable,表明伺服器暫時處於超負載或正在停機維護,無法處理請求
http method
get
GET方法用於使用給定的URI從給定伺服器中檢索資訊,即從指定資源中請求資料。使用GET方法的請求應該只是檢索資料,並且不應對資料產生其他影響。
post
POST方法用於將資料傳送到伺服器以建立或更新資源,它要求伺服器確認請求中包含的內容作為由URI區分的Web資源的另一個下屬。 POST請求永遠不會被快取,且對資料長度沒有限制;我們無法從瀏覽器歷史記錄中查詢到POST請求。 在規範的應用場景上說,Get 多用於無副作用,冪等的場景,例如搜尋關鍵字。Post 多用於副作用,不冪等的場景,例如註冊。
put
PUT方法用於將資料傳送到伺服器以建立或更新資源,它可以用上傳的內容替換目標資源中的所有當前內容。 它會將包含的元素放在所提供的URI下,如果URI指示的是當前資源,則會被改變。如果URI未指示當前資源,則伺服器可以使用該URI建立資源。
delete
DELETE方法用來刪除指定的資源,它會刪除URI給出的目標資源的所有當前內容。
head
HEAD方法與GET方法相同,但沒有響應體,僅傳輸狀態行和標題部分。這對於恢復相應頭部編寫的後設資料非常有用,而無需傳輸整個內容。
OPTIONS
OPTIONS方法用來描述了目標資源的通訊選項,會返回伺服器支援預定義URL的HTTP策略。(cors預請求瞭解一下,阮大神系列http://www.ruanyifeng.com/blog/2016/04/cors.html)
https
HTTP是明文傳輸的,也就意味著,介於傳送端、接收端中間的任意節點都可以知道你們傳輸的內容是什麼。這些節點可能是路由器、代理等。
HTTPS相對於HTTP有哪些不同呢?其實就是在HTTP跟TCP中間加多了一層加密層TLS/SSL。
什麼是TLS/SSL?
通俗的講,TLS、SSL其實是類似的東西,SSL是個加密協議,負責對HTTP的資料進行加密。TLS是SSL的升級版。現在提到HTTPS,加密協議基本指的是TLS。
先來了解一點概念
對稱加密:
對稱加密就是兩邊擁有相同的祕鑰,兩邊都知道如何將密文加密解密。
非對稱加密:
有公鑰私鑰之分,公鑰所有人都可以知道,可以將資料用公鑰加密,但是將資料解密必須使用私鑰解密,私鑰只有分發公鑰的一方才知道。
TLS握手流程
由上圖可知,先進行TCP的三次握手之後,就開始TLS的三次握手,關於TLS的握手細節見下圖
1、clientHello
傳送cipher suites (支援的加密套件列表) 和 random number到伺服器
2、serverHello
傳送random number, 證書(certificate),選擇的cipher suite 到客戶端
3、客戶端驗證證書(驗證細節見下文)
從證書中拿到公鑰, 生成預主鑰(pre master secret),用公鑰加密預主鑰,傳輸到服務端
我們也可以來看看阮大神的愛麗絲版
開始加密通訊之前,客戶端和伺服器首先必須建立連線和交換引數,這個過程叫做握手(handshake)。
假定客戶端叫做愛麗絲,伺服器叫做鮑勃,整個握手過程可以用下圖說明。
第二步,鮑勃確認雙方使用的加密方法,並給出數字證書、以及一個伺服器生成的隨機數(Server random)。
第三步,愛麗絲確認數字證書有效,然後生成一個新的隨機數(Premaster secret),並使用數字證書中的公鑰,加密這個隨機數,發給鮑勃。 第四步,鮑勃使用自己的私鑰,獲取愛麗絲髮來的隨機數(即Premaster secret)。
第五步,愛麗絲和鮑勃根據約定的加密方法,使用前面的三個隨機數,生成"對話金鑰"(session key),用來加密接下來的整個對話過程。
結論: 公鑰加密對稱演算法的私鑰傳到服務端,服務端用私鑰解密,這個時候客戶端和服務端都擁有同一個對稱演算法的私鑰, 開始加密傳輸吧。
session 恢復連線
握手階段用來建立SSL連線。如果出於某種原因,對話中斷,就需要重新握手。
這時有兩種方法可以恢復原來的session:一種叫做session ID,另一種叫做session ticket。
session ID的思想很簡單,就是每一次對話都有一個編號(session ID)。如果對話中斷,下次重連的時候,只要客戶端給出這個編號,且伺服器有這個編號的記錄,雙方就可以重新使用已有的"對話金鑰",而不必重新生成一把。
客戶端如何驗證證書的真偽
還是先來了解一點概念
CA 機構
又稱為證書認證中心 (Certificate Authority) 中心,是一個負責發放和管理數字證書的第三方權威機構,它負責管理PKI結構下的所有使用者(包括各種應用程式)的證書,把使用者的公鑰和使用者的其他資訊捆綁在一起,在網上驗證使用者的身份。CA機構的數字簽名使得攻擊者不能偽造和篡改證書。
CA根證書:
CA本身有自己的證書,江湖人稱“根證書”。這個“根證書”是用來證明CA的身份的,本質是一份普通的數字證書。
瀏覽器通常會內建大多數主流權威CA的根證書。
證書內容
內容非常多,這裡我們需要關注的有幾個點:
證書包含了頒發證書的機構的名字 -- CA
證書內容本身的數字簽名(用CA私鑰加密)
證書持有者的公鑰
證書籤名用到的hash演算法
數字簽名與摘要
簡單的來說,“摘要”就是對傳輸的內容,通過hash演算法計算出一段固定長度的串(是不是聯想到了文章摘要)。然後,在通過CA的私鑰對這段摘要進行加密,加密後得到的結果就是“數字簽名”。
1、防偽造
這種情況比較簡單,對證書進行檢查:
證書頒發的機構是偽造的:瀏覽器不認識,直接認為是危險證書
證書頒發的機構是確實存在的,於是根據CA名,找到對應內建的CA根證書、CA的公鑰。
用CA的公鑰,對偽造的證書的摘要進行解密,發現解不了。認為是危險證書
2、防篡改
假設代理通過某種途徑,拿到XX的證書,然後將證書的公鑰偷偷修改成自己的,然後喜滋滋的認為使用者要上鉤了。然而太單純了:
檢查證書,根據CA名,找到對應的CA根證書,以及CA的公鑰。
用CA的公鑰,對證書的數字簽名進行解密,得到對應的證書摘要AA
根據證書籤名使用的hash演算法,計算出當前證書的摘要BB
對比AA跟BB,發現不一致--> 判定是危險證書
以上關於https介紹大部分來自於
imweb.io/topic/56d67…
www.ruanyifeng.com/blog/2014/0…
http2.0
在寫http2.0之前先看看http1.1的一些特性
http1.1
特點:
長連線:
TCP連結會很慢,因為三次握手、滑動視窗、慢啟動等的消耗,儘量減少TCP連結。 長連線即TCP連線預設不關閉,可以被多個請求複用,宣告Connection: keep-alive就可以了。客戶端和伺服器發現對方一段時間沒有活動,就可以主動關閉連線 ,但是這只是解決了請求序列,並沒有解決並行
管道機制和線頭阻塞:
即在同一個TCP連線裡面,客戶端可以同時傳送多個請求。這樣就進一步改進了HTTP協議的效率。 其實HTTP管道化就是將客戶端的FIFO佇列移到了服務端。在客戶端可以依次傳送所有要傳送的請求(當然這些請求是在同一個域下的),一 個請求傳送完之後,不必等待這個請求的響應被接受到,下一個請求就可以被再次發出。在伺服器端維持的FIFO佇列,這個佇列是按照資源的重要程度排列的。 比如HTML比CSS要先返回,JS,CSS比圖片先返回。 如果前面請求的響應花了很長的時間,後面的請求也還是需要等待(被阻塞),這就是線頭阻塞
所以這個方案並沒有實際解決同一個TCP併發請求的問題。瀏覽器限制TCP連結:
在HTTP1.1中,瀏覽器客戶端可以,但是在同一時間針對同一域名下的TCP連結有一定數量的限制(一般是6-8個TCP連結)。超過限制數目的請求會被阻塞。 為了避免這個問題,只有兩種方法:一是減少請求數,二是同時多開持久連線。這導致了很多的網頁優化技巧,比如合併指令碼和樣式表、將圖片嵌入CSS程式碼、域名分片/發散(domain sharding)等等
spdy協議
SPDY(讀作“SPeeDY”)是Google開發的基於TCP的會話層 協議,用以最小化網路延遲,提升網路速度,優化使用者的網路使用體驗。SPDY並不是一種用於替代HTTP的協議,而是對HTTP協議的增強。
定位
將頁面載入時間減少50%。
最大限度地減少部署的複雜性。SPDY使用TCP作為傳輸層,因此無需改變現有的網路設施。
避免網站開發者改動內容。 支援SPDY唯一需要變化的是客戶端代理和Web伺服器應用程式。
具體技術目標
單個TCP連線支援併發的HTTP請求。
壓縮報頭和去掉不必要的頭部來減少當前HTTP使用的頻寬。
定義一個容易實現,在伺服器端高效率的協議。通過減少邊緣情況、定義易解析的訊息格式來減少HTTP的複雜性。
強制使用SSL,讓SSL協議在現存的網路設施下有更好的安全性和相容性。
允許伺服器在需要時發起對客戶端的連線並推送資料。
http2.0 SPDY的升級版
二進位制分幀傳輸
幀:HTTP2.0通訊的最小單位,所有幀都共享一個8位元組的首部,其中包含幀的長度、型別、標誌、還有一個保留位,並且至少有標識出當前幀所屬的流的識別符號,幀承載著特定型別的資料,如HTTP首部、負荷、等等。
訊息:比幀大的通訊單位,是指邏輯上的HTTP訊息,比如請求、響應等。由一個或多個幀組成
流:比訊息大的通訊單位。是TCP連線中的一個虛擬通道,可以承載雙向的訊息。每個流都有一個唯一的整數識別符號
在二進位制分幀層上,HTTP2.0會將所有傳輸資訊分割為更小的訊息和幀,並對它們採用二進位制格式的編碼將其封裝。其中,HTTP1.X中的首部資訊header封裝到Headers幀中,而request body將被封裝到Data幀中。 二進位制分幀主要是為下文中的各種特性提供了基礎。它能把一個資料劃分封裝為更小更便捷的資料。首先是在單連結多資源方式中,減少了服務端的連結壓力,記憶體佔用更少,連結吞吐量更大。這一點可以結合下文中的多路複用來體會。另一方面,由於TCP連結的減少而使網路擁塞狀態得以改善,同時慢啟動時間的減少。使擁塞和丟包恢復的速度更快。 HTTP 2.0 中所有加強效能的核心點在於此
多路複用
基於二進位制分幀層,HTTP2.0可以在共享TCP連結的基礎上同時傳送請求和響應。HTTP訊息被分解為獨立的幀,而不破壞訊息本身的語義,交錯發出去,在另一端根據流識別符號和首部將他們重新組裝起來。
1、可以並行交錯的傳送請求和響應,這些請求和響應之間互不影響
2、只使用一個連結即可並行傳送多個請求和響應
3、消除不必要的延遲,從而減少頁面載入的時間
4、不必再為繞過HTTP1.x限制而多做很多工作
5、多路複用完美的解決了線頭阻塞問題。
請求優先順序
每個流都可以帶有一個31bit的優先值:0表示最高優先順序;2的31次方-1表示最低優先順序。
客戶端明確指定優先順序,服務端可以根據這個優先順序作為互動資料的依據,比如客戶端優先設定為.css>.js>.jpg。服務端按此順序返回結果更加有利於高效利用底層連線,提高使用者體驗。然而,在使用請求優先順序時應注意服務端是否支援請求優先順序,是否會引起隊首阻塞問題,比如高優先順序的慢響應請求會阻塞其他資源的互動。
頭部壓縮
在 HTTP 1.X 中,我們使用文字的形式傳輸 header,在 header 攜帶 cookie 的情況下,可能每次都需要重複傳輸幾百到幾千的位元組。 在 HTTP 2.0 中,使用了 HPACK 壓縮格式對傳輸的 header 進行編碼,減少了 header 的大小。並在兩端維護了索引表,用於記錄出現過的 header ,後面在傳輸過程中就可以傳輸已經記錄過的 header 的鍵名,對端收到資料後就可以通過鍵名找到對應的值。
伺服器推送
在 HTTP 2.0 中,服務端可以在客戶端某個請求後,主動推送其他資源。 可以想象以下情況,某些資源客戶端是一定會請求的,這時就可以採取服務端 push 的技術,提前給客戶端推送必要的資源,這樣就可以相對減少一點延遲時間。當然在瀏覽器相容的情況下你也可以使用 prefetch 。