超文本傳輸協議(HyperText Transfer Protocol), 是一種用於分佈式、協做式和超媒體信息系統的應用層協議, 是萬維網的數據通訊的基礎(維基百科)。這裏咱們主要關注一下什麼是應用層,以及網絡是如何分層的.html
網絡爲何要分層[1]?web
開放式系統互聯通訊參考模型,由國際標準化組織提出。
OSI
將網絡分爲七層: 應用層、表示層、會話層、傳輸層、網絡層、鏈路層、物理層。算法
TCP/IP
是實際的標準, 分爲五層: 應用層、傳輸層、網絡層、鏈路層、物理層。瀏覽器
TCP/IP
與OSI
的分層的對應關係, 以下圖所示:
緩存
TCP/IP
也能夠說是四層, 若是是四層的話就是把鏈路層與物理層統稱爲網絡接口層。安全
讓咱們從一次請求過程來了解HTTP
。bash
URL
以後,首先須要DNS
來將域名解析爲IP
地址。TCP
鏈接(三次握手),創建鏈接的時候是須要發送IP
包的。HTTPS
會進行TLS/SSL
的握手。鏈接創建之後,就是要向服務器發送請求,那麼請求格式是怎麼樣的呢? HTTP1.1爲明文傳輸,因此咱們很容易可以在Chrome
的Network
中看到,請求的格式以下圖所示:
服務器
從上圖能夠看出,請求分爲了三部分:請求行,首部,實體。websocket
首部與實體之間使用空行分隔。網絡
請求行由三部分構成:方法,URL
,HTTP
版本號,以空格隔開。
主要的方法有:GET
POST
OPTIONS
HEAD
等
GET
若是有參數,會將其放在URL
中: 優勢:
URL
能夠被緩存TCP
第三次握手時將報文隨握手包發送)。 缺點:URL
的長度)GET
請求的過程[2]:
TCP
鏈接(第一次握手)TCP
鏈接(第二次握手)GET
請求頭和數據200 OK
響應POST
參數存在於實體中: 優勢:
GET
,抓包除外)。 缺點:GET
多了幾個用於協商的首部,且須要待第三次握手後再發送報文)。POST
請求的過程[2]:
TCP
鏈接(第一次握手)TCP
鏈接(第二次握手)POST
請求頭(第三次握手)100 Continue
響應200 OK
響應OPTIONS
HEAD
請求資源的首部信息, 而且這些首部與GET
方法請求時返回的一致。響應不該包含響應實體,即便包含了實體也必須忽略掉。
URL
(Uniform Resource Locator), 統一資源定位符, 是因特網上標準的資源的地址。
完整格式:協議類型:[//[訪問資源須要的憑證信息@]服務器地址[:端口號]][/資源層級UNIX文件路徑]文件名[?查詢][#片斷ID]
另外,與URL
相關的定義還有URI
和URN
。 URI
(Uniform Resource Identifier),統一資源標識符,用於標識某一互聯網資源名稱的字符串。 URN
(Uniform Resource Name),統一資源名稱,一種爲資源提供持久的、位置無關的標識方式。
URL
與URN
是URI
的子集,三者關係,以下圖所示:
舉個栗子:
urn:isbn:0-486-27557-4
這是一個資源,它是URN
,也是URI
,但不是URL
。
HTTP
版本主要版本:0.九、1.0、1.1、2
首部是key: value
形式,經過冒號空格分隔,爲客戶端和服務器分別處理請求和相應提供所須要的信息。 首部分爲四類:請求首部,響應首部,通用首部,實體首部。
顧名思義,只會在請求報文中存在。
Accept-Charset
:客戶端支持的字符集,例:utf-8
。Accept-Encoding
:客戶端能夠接受的內容編碼形式,例:gzip
。Referer
:對請求中URL
的原始獲取方。Host
:請求資源所在服務器。Accept-Language
:提示用戶指望得到的天然語言的優先順序。User-Agent
:用來識別發送請求的瀏覽器。Cache-Control
:緩存控制。Content-Encoding
:實體的編碼方式。Content-Language
:實體的天然語言。Content-Type
:實體的媒體類型。Location
:令客戶端重定向至指定URL
。Retry-After
:對再次發起請求的時機要求。Server
:HTTP
服務器的安裝信息。ETag
:資源匹配信息(緩存相關)。一切準備完成後就是發送請求。
請求發送接收的過程以下圖所示:
HTTP
構建完成後,經過網絡線程將請求報文交給TCP
。TCP
將請求的報文進行分割,並將各個報文包入TCP
的頭部,交給IP
。IP
將TCP
報文包入IP
的頭部,交個鏈路層。MAC
地址是否爲本身的MAC
地址,若是是會把以太網頭部去除,交個上層協議。IP
收到鏈路層發送的數據後,會檢查目標IP
是否爲本身的IP
,若是是把IP
頭部去除,交給上層協議。TCP
收到數據後,去掉TCP
頭部,交給瀏覽器。響應與請求除了狀態行外結構基本相同,一樣分爲 3 部分:狀態行,首部,實體。
狀態行分爲 3 部分:HTTP版本,狀態碼,短語,以空格分隔,其中短語爲對狀態碼的解釋。
PUT
請求中進行資源更新,可是不須要改變當前展現給用戶的頁面,那麼返回204 No Content
。例如:提交表單後,不進行頁面跳轉)。GET
請求。響應報文中包含由Content-Range
指定範圍的的實體內容。URL
,之後請使用資源如今所指的URL
。搜索引擎會根據該響應修正。URL
,但願用戶(本次)能使用新的URL
訪問。已改變,且未來還有可能發生改變。URL
,應使用GET
方法定向獲取請求的資源。(301
、302
、303
響應狀態碼返回時幾乎全部的瀏覽器都會把POST
改爲 GET
,並刪除請求報文的主體,以後請求會自動再次發送。)。302
之間的惟一區別在於,當發送重定向請求的時候,307
狀態碼能夠確保請求方法和消息主體不會發生變化。200 OK
同樣對待該狀態碼。WWW-Authenticate
首部一塊兒發送,其中包含有如何進行驗證的信息。Retry-After
首部字段再返回給客戶端。在完成了響應的構建以後,會按照與發送相同的方式將響應發送給客戶端。最後TCP
四次回收斷開鏈接。
整個請求過程以下圖所示:
HTTP/0.9很是簡單,請求僅由單行構成,以惟一可用方法GET
開頭,其後跟目標資源的路徑。
GET /index.html
響應也很是簡單僅包含響應文檔自己,若是出現錯誤會將錯誤信息以文檔形式返回。
主要引入了頭部,及狀態碼,並支持多種文件格式。
HTTP/1.1 相對 1.0 的不一樣:
Keep-Alive
,全部鏈接都被保持,除非在請求頭或響應頭中指明要關閉:Connection: Close
。Keep-Alive
不會永久保持鏈接,它有一個保持時間,能夠在不一樣的服務器軟件中設定這個時間(實際是在1.0
版本引入,但並不會默認開啓)。Cache-Control
等。TCP
端口號。與 HTTP/1.1
的區別:
TCP
鏈接中能夠同時發送多個請求。瀏覽器在首次對資源進行請求時,會記錄緩存相關的首部,在後續請求中根據記錄的首部進行相應的資源讀取操做,如讀取緩存,資源驗證等。 緩存的做用:減小請求次數,減小帶寬;增長加載速度,減小白屏時間。
在說明緩存控制原理以前,先了解下緩存相關的首部。
控制緩存的有效時間,及緩存行爲。
主要值:
對於 Cache-Control: no-cache, max-age=900 這種狀況,no-cache 與 max-age 的優先級與前後順序有關。
爲HTTP/1.0
提出,表示緩存過時時間,超過這個時間即緩存過時。若是響應中有max-age
或s-maxage
會被覆蓋。
expires: Sun, 02 Sep 2018 14:36:18 GMT
資源的最後修改時間,主要用於在服務器驗證緩存是否被修改時使用。
last-modified: Fri, 18 May 2018 01:10:24 GMT
資源實體標識,由服務器分配,資源更新時ETge
隨之改變,分爲強ETag
與弱ETag
。 **弱ETag
**很容易生成,但不利於比較。**強ETag
**是比較的理想選擇,但很難有效地生成。
ETag: W/"5a323f72-152"(弱) ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"(強)
200 (from memory/disk cache)
。ETag
及Last-Modified
,若是存在,則在請求首部中發送對應的首部If-None-Match
及If-Modified-Since
,若是沒有則不發送這兩個首部。If-None-Match
及If-Modified-Since
來比較資源的ETag
若是改變了比較Last-Modified
,若是匹配則返回304
,若是不匹配,將資源隨實體返回,狀態碼200
。from memory cache 與 from disk cache 爲 Chrome 的緩存優化機制,但對於該採用什麼方式,並無找到明確答案。
強緩存:不會向服務器發送請求,直接讀取緩存的方式,在上述過程當中直接返回狀態碼200 (from memory/disk cache)
。 協商緩存:請求資源時會向服務器發送If-None-Match
及If-Modified-Since
(若是存在ETag
及Last-Modified
),服務器驗證後,返回304
或200
。
在學習HTTPS
以前,咱們瞭解下HTTP
的缺點:
而HTTPS
解決了上述缺點(HTTPS
並不是新協議,而是HTTP
+ TLS
)
發送端和接收端使用相同的密鑰。發送端使用密鑰加密明文,接收端接收後使用密鑰解析加密信息,獲得明文。
對稱加密最大的問題就是在一對多的時候的密鑰傳輸問題,因此爲了保證安全對稱加密的密鑰是絕對不能公開的。
非對稱加密有兩個密鑰,一個是公鑰,一個是私鑰,公鑰加密後的密文只能使用私鑰解密,私鑰加密後的密文只能使用公鑰解密。那麼只須要對外展現公鑰就能夠了。
可是,非對稱加密的解密過程速度較慢(對稱加密主要是位運算,而非對稱加密包含了不少乘法或大數模)。
充分利用對稱及非對稱加密的優點,使用非對稱加密的方式傳輸對稱加密的密鑰,即有非對稱加密的安全又有對稱加密的速度。 HTTPS
(或者說TLS
)就是採用了這種方式。
CA
在拿到公鑰後,能不能就直接肯定這個公鑰是值得信任的?答案是確定不能,若是公鑰是某個黑客僞造的,他就能夠修改從發送端接到的請求,在發給服務器了。因此,在拿到公鑰後,首先要驗證公鑰是否是能夠信任的,那麼誰能保證公鑰是能夠信任的,那就必需要是一個你信任的機構,這個機構就是CA
,而每一個站點的公鑰實際都是由CA
簽發的。因此CA
能夠驗證公鑰是否屬於這個站點的。
CA
CA
使用本身的私鑰向服務器的公鑰部署數字簽名,並頒發公鑰證書CA
的公鑰(存在於客戶端證書信任列表中)去驗證簽名是否與公鑰匹配。TCP
三次握手後,客戶端發送請求安全鏈接(Client Hello),報文中包含一個隨機字符串,並列出客戶端支持的加密套件,用於協商對稱加密的加密方式。CA
,使用該CA
的公鑰解密證書,來驗證公鑰是否安全,若是CA
的證書由上級CA
提供且不在信任列表內,則須要一直向上找到客戶端信任的CA
爲止。Pre-master secret
的隨機字符串,客戶端及服務器端使用上面提到的三個隨機字符串,並使用協商好的加密算法計算出對稱加密的密鑰。Change Cipher Spec
報文,以提示服務器後續通訊將採用計算好的對稱加密密鑰進行通訊Finished
報文,報文中包含鏈接至今所有報文的總體校驗值,若是服務器端可以正確解密該報文,則握手成功Change Cipher Spec
報文Finished
報文,鏈接創建。WebSocket
是能夠實現客戶端與服務器端雙向通訊的新協議,除了藉助HTTP
完成一次握手外,與HTTP
沒有關係。
TCP
三次握手。Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
複製代碼
上述首部中主要是用到了Upgrade
首部,用於通知服務器切換協議到WebSocket
。 3. 服務器端接收到升級協議的請求後,若是支持WebSocket
會響應該請求。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
複製代碼
響應狀態碼:101,表示服務器端應客戶端升級協議的請求正在升級協議。 4. WebSocket
握手完成,後續通訊將使用WebSocket
協議。
參考:
[1]《計算機網絡(第五版)》(謝希仁)
[2] http GET 和 POST 請求的優缺點、區別以及誤區
[3] TLS 握手優化詳解