HTTP
協議(超文本傳輸協議HyperText Transfer Protocol),它是基於TCP協議的應用層傳輸協議,簡單來講就是客戶端和服務端進行數據傳輸的一種規則。html
注意:客戶端與服務器的角色不是固定的,一端充當客戶端,也可能在某次請求中充當服務器。這取決與請求的發起端。HTTP協議屬於應用層,創建在傳輸層協議TCP之上。客戶端經過與服務器創建TCP鏈接,以後發送HTTP請求與接收HTTP響應都是經過訪問Socket接口來調用TCP協議實現。web
HTTP
是一種無狀態 (stateless) 協議, HTTP
協議自己不會對發送過的請求和相應的通訊狀態進行持久化處理。這樣作的目的是爲了保持HTTP協議的簡單性,從而可以快速處理大量的事務, 提升效率。算法
然而,在許多應用場景中,咱們須要保持用戶登陸的狀態或記錄用戶購物車中的商品。因爲HTTP
是無狀態協議,因此必須引入一些技術來記錄管理狀態,例如Cookie
。編程
HTTP URL
包含了用於查找某個資源的詳細信息, 格式以下:後端
http://host[":"port][abs_path]
複製代碼
下圖是在網上找的一張圖,以爲能很好的表達HTTP請求的所發送的數據格式。瀏覽器
由上圖能夠看到,http請求由請求行,消息報頭,請求正文三部分構成。緩存
請求行由請求Method
, URL
字段和HTTP Version
三部分構成, 總的來講請求行就是定義了本次請求的請求方式, 請求的地址, 以及所遵循的HTTP協議版本例如:安全
GET /example.html HTTP/1.1 (CRLF)
複製代碼
HTTP協議的方法有:bash
GET
: 請求獲取Request-URI所標識的資源POST
: 在Request-URI所標識的資源後增長新的數據HEAD
: 請求獲取由Request-URI所標識的資源的響應消息報頭PUT
: 請求服務器存儲或修改一個資源,並用Request-URI做爲其標識DELETE
: 請求服務器刪除Request-URI所標識的資源TRACE
: 請求服務器回送收到的請求信息,主要用於測試或診斷CONNECT
: 保留未來使用OPTIONS
: 請求查詢服務器的性能,或者查詢與資源相關的選項和需求消息報頭由一系列的鍵值對組成,容許客戶端向服務器端發送一些附加信息或者客戶端自身的信息,主要包括:服務器
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 |
只有在發送POST
請求時纔會有請求正文,GET
方法並無請求正文。
與HTTP請求相似,先上一張圖:
HTTP響應也由三部分組成,包括狀態行,消息報頭,響應正文。
狀態行也由三部分組成,包括HTTP協議的版本,狀態碼,以及對狀態碼的文本描述。例如:
HTTP/1.1 200 OK (CRLF)
複製代碼
狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值:
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 - 服務器當前不能處理客戶端的請求,一段時間後,可能恢復正常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協議的版本,沒法完成處理 |
GET
、HEAD
、POST
。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP
協議簡單,使得HTTP
服務器的程序規模小,於是通訊速度很快。Content-Type
加以標記。Connection: Keep-Alive
實現長鏈接HTTP
協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。在實際的應用中,客戶端每每會發出一系列請求,接着服務器端對每一個請求進行響應。對於這些請求|響應,若是每次都通過一個單獨的TCP鏈接發送,稱爲非持久鏈接。反之,若是每次都通過相同的TCP鏈接進行發送,稱爲持久鏈接。
非持久鏈接在每次請求|響應以後都要斷開鏈接,下次再創建新的TCP鏈接,這樣就形成了大量的通訊開銷。例如前面提到的往返時間(RTT)
就是在創建TCP鏈接的過程當中的代價。
非持久鏈接給服務器帶來了沉重的負擔,每臺服務器可能同時面對數以百計甚至更多的請求。持久鏈接就是爲了解決這些問題,其特色是一直保持TCP鏈接狀態,直到遇到明確的中斷要求以後再中斷鏈接。持久鏈接減小了通訊開銷,節省了通訊量。
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與瀏覽器是否一致(驗證瀏覽器)
複製代碼
歡迎關注技術公衆號: 零壹技術棧
本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。