簡介
HTTP
協議(超文字傳輸協議HyperText Transfer Protocol),它是基於TCP協議的應用層傳輸協議,簡單來說就是客戶端和服務端進行資料傳輸的一種規則。
注意:客戶端與伺服器的角色不是固定的,一端充當客戶端,也可能在某次請求中充當伺服器。這取決與請求的發起端。HTTP協議屬於應用層,建立在傳輸層協議TCP之上。客戶端通過與伺服器建立TCP連線,之後傳送HTTP請求與接收HTTP響應都是通過訪問Socket介面來呼叫TCP協議實現。
HTTP
是一種無狀態 (stateless) 協議, HTTP
協議本身不會對傳送過的請求和相應的通訊狀態進行持久化處理。這樣做的目的是為了保持HTTP協議的簡單性,從而能夠快速處理大量的事務, 提高效率。
然而,在許多應用場景中,我們需要保持使用者登入的狀態或記錄使用者購物車中的商品。由於HTTP
是無狀態協議,所以必須引入一些技術來記錄管理狀態,例如Cookie
。
正文
HTTP URL
HTTP URL
包含了用於查詢某個資源的詳細資訊, 格式如下:
http://host[":"port][abs_path]
複製程式碼
HTTP請求
下圖是在網上找的一張圖,覺得能很好的表達HTTP請求的所傳送的資料格式。
由上圖可以看到,http請求由請求行,訊息報頭,請求正文三部分構成。
HTTP請求狀態行
請求行由請求Method
, URL
欄位和HTTP Version
三部分構成, 總的來說請求行就是定義了本次請求的請求方式, 請求的地址, 以及所遵循的HTTP協議版本例如:
GET /example.html HTTP/1.1 (CRLF)
複製程式碼
HTTP協議的方法有:
GET
: 請求獲取Request-URI所標識的資源POST
: 在Request-URI所標識的資源後增加新的資料HEAD
: 請求獲取由Request-URI所標識的資源的響應訊息報頭PUT
: 請求伺服器儲存或修改一個資源,並用Request-URI作為其標識DELETE
: 請求伺服器刪除Request-URI所標識的資源TRACE
: 請求伺服器回送收到的請求資訊,主要用於測試或診斷CONNECT
: 保留將來使用OPTIONS
: 請求查詢伺服器的效能,或者查詢與資源相關的選項和需求
HTTP請求頭
訊息報頭由一系列的鍵值對組成,允許客戶端向伺服器端傳送一些附加資訊或者客戶端自身的資訊,主要包括:
Header | 解釋 | 示例 |
---|---|---|
Accept | 指定客戶端能夠接收的內容型別 | Accept: text/plain, text/html |
Accept-Charset | 瀏覽器可以接受的字元編碼集 | Accept-Charset: iso-8859-5,utf-8 |
Accept-Encoding | 指定瀏覽器可以支援的web伺服器返回內容壓縮編碼型別 | Accept-Encoding: compress, gzip |
Accept-Language | 瀏覽器可接受的語言 | Accept-Language: en,zh |
Accept-Ranges | 可以請求網頁實體的一個或者多個子範圍欄位 | Accept-Ranges: bytes |
Authorization | HTTP授權的授權證書型別 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定請求和響應遵循的快取機制 | Cache-Control: no-cache |
Connection | 表示是否需要持久連線(HTTP 1.1預設進行持久連線) | Connection: close |
Cookie | HTTP請求傳送時,會把儲存在該請求域名下的所有cookie值一起傳送給web伺服器 | Cookie: $Version=1; Skin=new; |
Content-Length | 請求的內容長度 | Content-Length: 348 |
Content-Type | 請求的與實體對應的MIME資訊 | Content-Type: application/x-www-form-urlencoded |
Date | 請求傳送的日期和時間 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 請求的特定的伺服器行為 | Expect: 100-continue |
From | 發出請求的使用者的Email | From: user@email.com |
Host | 指定請求的伺服器的域名和埠號 | Host: www.zcmhi.com |
If-Match | 只有請求內容與實體相匹配才有效 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 如果請求的部分在指定時間之後被修改則請求成功,未被修改則返回304程式碼 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果內容未改變返回304程式碼,引數為伺服器先前傳送的Etag,與伺服器迴應的Etag比較判斷是否改變 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range | 如果實體未改變,伺服器傳送客戶端丟失的部分,否則傳送整個實體。引數也為Etag | If-Range: “737060cd8c284d8af7ad3082f209582d” |
If-Unmodified-Since | 只在實體在指定時間之後未被修改才請求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制資訊通過代理和閘道器傳送的時間 | Max-Forwards: 10 |
Pragma | 用來包含實現特定的指令 | Pragma: no-cache |
Proxy-Authorization | 連線到代理的授權證書 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只請求實體的一部分,指定範圍 | Range: bytes=500-999 |
Referer | 先前網頁的地址,當前請求網頁緊隨其後, 即來路 | Referer: www.zcmhi.com/archives/71… |
TE | 客戶端願意接受的傳輸編碼,並通知伺服器接受接受尾加頭資訊 | TE: trailers,deflate;q=0.5 |
Upgrade | 向伺服器指定某種傳輸協議以便伺服器進行轉換(如果支援) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | User-Agent的內容包含發出請求的使用者資訊 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中間閘道器或代理伺服器地址,通訊協議 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 關於訊息實體的警告資訊 | Warn: 199 Miscellaneous warning |
HTTP請求正文
只有在傳送POST
請求時才會有請求正文,GET
方法並沒有請求正文。
HTTP請求報文
HTTP響應
與HTTP請求類似,先上一張圖:
HTTP響應也由三部分組成,包括狀態行,訊息報頭,響應正文。
HTTP響應狀態行
狀態行也由三部分組成,包括HTTP協議的版本,狀態碼,以及對狀態碼的文字描述。例如:
HTTP/1.1 200 OK (CRLF)
複製程式碼
HTTP響應狀態碼
狀態程式碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值:
1xx
:指示資訊 - 表示請求已接收,繼續處理2xx
:成功 - 表示請求已被成功接收、理解、接受3xx
:重定向 - 要完成請求必須進行更進一步的操作4xx
:客戶端錯誤 - 請求有語法錯誤或請求無法實現5xx
:伺服器端錯誤 - 伺服器未能實現合法的請求
常見狀態程式碼、狀態描述、說明:
200
: OK - 客戶端請求成功400
: Bad Request - 客戶端請求有語法錯誤,不能被伺服器所理解401
: Unauthorized - 請求未經授權,這個狀態程式碼必須和WWW-Authenticate
報頭域一起使用403
: Forbidden - 伺服器收到請求,但是拒絕提供服務404
: Not Found - 請求資源不存在,eg:輸入了錯誤的URL500
: Internal Server Error - 伺服器發生不可預期的錯誤503
: Server Unavailable - 伺服器當前不能處理客戶端的請求,一段時間後,可能恢復正常
HTTP響應狀態碼說明
StatusCode | StatusCode語義 | 中文描述 |
---|---|---|
100 | Continue | 繼續。客戶端應繼續其請求 |
101 | Switching Protocols | 切換協議。伺服器根據客戶端的請求切換協議。只能切換到更高階的協議,例如,切換到HTTP的新版本協議 |
200 | OK | 請求成功。一般用於GET與POST請求 |
201 | Created | 已建立。成功請求並建立了新的資源 |
202 | Accepted | 已接受。已經接受請求,但未處理完成 |
203 | Non-Authoritative Information | 非授權資訊。請求成功。但返回的meta資訊不在原始的伺服器,而是一個副本 |
204 | No Content | 無內容。伺服器成功處理,但未返回內容。在未更新網頁的情況下,可確保瀏覽器繼續顯示當前文件 |
205 | Reset Content | 重置內容。伺服器處理成功,使用者終端(例如:瀏覽器)應重置文件檢視。可通過此返回碼清除瀏覽器的表單域 |
206 | Partial Content | 部分內容。伺服器成功處理了部分GET請求 |
300 | Multiple Choices | 多種選擇。請求的資源可包括多個位置,相應可返回一個資源特徵與地址的列表用於使用者終端(例如:瀏覽器)選擇 |
301 | Moved Permanently | 永久移動。請求的資源已被永久的移動到新URI,返回資訊會包括新的URI,瀏覽器會自動定向到新URI。今後任何新的請求都應使用新的URI代替 |
302 | Found 臨時移動。 | 與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI |
303 | See Other | 檢視其它地址。與301類似。使用GET和POST請求檢視 |
304 | Not Modified | 未修改。所請求的資源未修改,伺服器返回此狀態碼時,不會返回任何資源。客戶端通常會快取訪問過的資源,通過提供一個頭資訊指出客戶端希望只返回在指定日期之後修改的資源 |
305 | Use Proxy | 使用代理。所請求的資源必須通過代理訪問 |
306 | Unused | 已經被廢棄的HTTP狀態碼 |
307 | Temporary Redirect | 臨時重定向。與302類似。使用GET請求重定向 |
400 | Bad Request | 客戶端請求的語法錯誤,伺服器無法理解 |
401 | Unauthorized | 請求要求使用者的身份認證 |
402 | Payment Required | 保留,將來使用 |
403 | Forbidden | 伺服器理解請求客戶端的請求,但是拒絕執行此請求 |
404 | Not Found | 伺服器無法根據客戶端的請求找到資源(網頁)。通過此程式碼,網站設計人員可設定"您所請求的資源無法找到"的個性頁面 |
405 | Method Not Allowed | 客戶端請求中的方法被禁止 |
406 | Not Acceptable | 伺服器無法根據客戶端請求的內容特性完成請求 |
407 | Proxy Authentication Required | 請求要求代理的身份認證,與401類似,但請求者應當使用代理進行授權 |
408 | Request Time-out | 伺服器等待客戶端傳送的請求時間過長,超時 |
409 | Conflict | 伺服器完成客戶端的PUT請求是可能返回此程式碼,伺服器處理請求時發生了衝突 |
410 | Gone | 客戶端請求的資源已經不存在。410不同於404,如果資源以前有現在被永久刪除了可使用410程式碼,網站設計人員可通過301程式碼指定資源的新位置 |
411 | Length Required | 伺服器無法處理客戶端傳送的不帶Content-Length的請求資訊 |
412 | Precondition Failed | 客戶端請求資訊的先決條件錯誤 |
413 | Request Entity Too Large | 由於請求的實體過大,伺服器無法處理,因此拒絕請求。為防止客戶端的連續請求,伺服器可能會關閉連線。如果只是伺服器暫時無法處理,則會包含一個Retry-After的響應資訊 |
414 | Request-URI Too Larg | 請求的URI過長(URI通常為網址),伺服器無法處理 |
415 | Unsupported Media Type | 伺服器無法處理請求附帶的媒體格式 |
416 | Requested range not satisfiable | 客戶端請求的範圍無效 |
417 | Expectation Failed | 伺服器無法滿足Expect的請求頭資訊 |
500 | Internal Server Error | 伺服器內部錯誤,無法完成請求 |
501 | Not Implemented | 伺服器不支援請求的功能,無法完成請求 |
502 | Bad Gateway | 充當閘道器或代理的伺服器,從遠端伺服器接收到了一個無效的請求 |
503 | Service Unavailable | 由於超載或系統維護,伺服器暫時的無法處理客戶端的請求。延時的長度可包含在伺服器的Retry-After頭資訊中 |
504 | Gateway Time-out | 充當閘道器或代理的伺服器,未及時從遠端伺服器獲取請求 |
505 | HTTP Version not supported | 伺服器不支援請求的HTTP協議的版本,無法完成處理 |
HTTP響應報文
HTTP協議詳解
HTTP的五大特點
- 支援客戶/伺服器模式。
- 簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有
GET
、HEAD
、POST
。每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP
協議簡單,使得HTTP
伺服器的程式規模小,因而通訊速度很快。 - 靈活:HTTP允許傳輸任意型別的資料物件。正在傳輸的型別由
Content-Type
加以標記。 - 無連線:無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。早期這麼做的原因是請求資源少,追求快。後來通過
Connection: Keep-Alive
實現長連線 - 無狀態:
HTTP
協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。
非持久連線和持久連線
在實際的應用中,客戶端往往會發出一系列請求,接著伺服器端對每個請求進行響應。對於這些請求|響應,如果每次都經過一個單獨的TCP連線傳送,稱為非持久連線。反之,如果每次都經過相同的TCP連線進行傳送,稱為持久連線。
非持久連線在每次請求|響應之後都要斷開連線,下次再建立新的TCP連線,這樣就造成了大量的通訊開銷。例如前面提到的往返時間(RTT)
就是在建立TCP連線的過程中的代價。
非持久連線給伺服器帶來了沉重的負擔,每臺伺服器可能同時面對數以百計甚至更多的請求。持久連線就是為了解決這些問題,其特點是一直保持TCP連線狀態,直到遇到明確的中斷要求之後再中斷連線。持久連線減少了通訊開銷,節省了通訊量。
HTTP和HTTPS
HTTP的不足
- 通訊使用明文(不加密),內容可能會被竊聽
- 不驗證通訊方的身份,因此有可能遭遇偽裝
- 無法證明報文的完整性,所以有可能已遭篡改
HTTPS介紹
HTTP
協議中沒有加密機制,但可以通 過和 SSL
(Secure Socket Layer, 安全套接層 )或 TLS
(Transport Layer Security, 安全層傳輸協議)的組合使用,加密 HTTP
的通訊內容。屬於通訊加密,即在整個通訊線路中加密。
HTTP + 加密 + 認證 + 完整性保護 = HTTPS(HTTP Secure )
複製程式碼
HTTPS
採用共享金鑰加密(對稱)和公開金鑰加密(非對稱)兩者並用的混合加密機制。若金鑰能夠實現安全交換,那麼有可能會考慮僅使用公開金鑰加密來通訊。但是公開金鑰加密與共享金鑰加密相比,其處理速度要慢。
所以應充分利用兩者各自的優勢, 將多種方法組合起來用於通訊。 在交換金鑰階段使用公開金鑰加密方式,之後的建立通訊交換報文階段 則使用共享金鑰加密方式。
HTTPS
握手過程的簡單描述如下:
-
瀏覽器將自己支援的一套加密規則傳送給網站。
伺服器獲得瀏覽器公鑰 複製程式碼
-
網站從中選出一組加密演算法與HASH演算法,並將自己的身份資訊以證書的形式發回給瀏覽器。證書裡面包含了網站地址,加密公鑰,以及證書的頒發機構等資訊。
瀏覽器獲得伺服器公鑰 複製程式碼
-
獲得網站證書之後瀏覽器要做以下工作:
(a). 驗證證書的合法性(頒發證書的機構是否合法,證書中包含的網站地址是否與正在訪問的地址一致等),如果證書受信任,則瀏覽器欄裡面會顯示一個小鎖頭,否則會給出證書不受信的提示。
(b). 如果證書受信任,或者是使用者接受了不受信的證書,瀏覽器會生成一串隨機數的密碼(接下來通訊的金鑰),並用證書中提供的公鑰加密(共享金鑰加密)。
(c) 使用約定好的HASH計算握手訊息,並使用生成的隨機數對訊息進行加密,最後將之前生成的所有資訊傳送給網站。
瀏覽器驗證 -> 隨機密碼 伺服器的公鑰加密 -> 通訊的金鑰 通訊的金鑰 -> 伺服器 複製程式碼
-
網站接收瀏覽器發來的資料之後要做以下的操作:
(a). 使用自己的私鑰將資訊解密取出密碼,使用密碼解密瀏覽器發來的握手訊息,並驗證HASH是否與瀏覽器發來的一致。
(b). 使用密碼加密一段握手訊息,傳送給瀏覽器。
伺服器用自己的私鑰解出隨機密碼 -> 用密碼解密握手訊息(共享金鑰通訊)-> 驗證HASH與瀏覽器是否一致(驗證瀏覽器) 複製程式碼
HTTPS的不足
- 加密解密過程複雜,導致訪問速度慢
- 加密需要認向證機構付費
- 整個頁面的請求都要使用HTTPS
歡迎關注技術公眾號: 零壹技術棧
本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。